MSP430 GCC 是否支持更新的 C++ 标准? (比如 11、14、17)

Does MSP430 GCC support newer C++ standards? (like 11, 14, 17)

我正在编写一些代码,这些代码将极大地受益于随 C++ 11 引入的 lambda 的简洁语法。编译器支持吗?

使用 Energia 或 embedXcode 编译时如何指定编译器标志?

TI 网站上关于此主题的内容不多,或者,至少,我对 C++ 的了解还不够多,无法为您提供详细而准确的答复。

this document that is mainly a derivation of the Itanium C++ ABI 中描述了嵌入式 ABI 的实现。它没有解释 lambda 的实现,也没有解释 auto 关键字(或者我可能无法从文档中获取此信息)。

于是决定直接在Energia测试。显然 g++ 版本是 4.6.3,因此它应该支持两者。

事实上(从编译的角度来看,我这里没有我的 MSP 来测试代码)它可以编译如下内容:

// In template.hpp
#ifndef TEMPLATE_HPP_
#define TEMPLATE_HPP_

template<class T>
T func(T a) {
  auto c = [&](int n) { return n + a; };
  return c(0);
}

#endif /* TEMPLATE_HPP_ */

// in the sketch main
#include "template.hpp"

void setup() { int b = func<int>(0); }
void loop() { }    

(模板仅在 header 中有效,在主草图中引发错误)。为了编译这个草图,我不得不修改编辑器的一个内部文件。最大支持的标准好像是-std=c++0x,编译标志在文件里:

$ENERGIA_ROOT/hardware/energia/msp430/platform.txt

在我的设置中,根位于 /opt/energia。在该文件中,我修改了 32 (compiler.cpp.flags) 行并添加了该选项。请注意 -std=c++11 不受支持(引发错误)。

compiler.cpp.flags=-std=c++0x -c -g -O2 {compiler.mlarge_flag} {compiler.warning_flags} -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD

不幸的是,我对 embedXcode 的经验为零:\

模仿std::function

未提供

std::function,因此您必须编写某种模仿它的 class。类似于:

// callback.hpp
#ifndef CALLBACK_HPP_
#define CALLBACK_HPP_

template <class RET, class ARG>
class Callback {
  RET (*_f)(ARG);

  public:
  Callback() : _f(0) { };
  Callback(RET (*f)(ARG)) : _f(f) { };
  bool is_set() const { return (_f) ? true : false; } 
  RET operator()(ARG a) const { return is_set() ?  _f(a) : 0; }
};

#endif /* CALLBACK_HPP_ */

// sketch
#include "callback.hpp"         
                              // | !! empty capture!
void setup() {                // V
  auto clb = Callback<int, char>([](char c) { return (int)c; });
  if (clb.is_set())
    auto b = clb('a');
}

void loop() {}

可以完成这项工作,它使用一个简单的技巧:

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. [C++11 standard 5.1.2]

只要您将捕获留空,就可以确保 "conversion" 指向函数指针,因此您可以毫无问题地存储它。我写的代码:

  • 需要作为返回类型的第一个模板RET
  • 需要第二个模板 ARG,它是回调的一个参数。在大多数情况下,您可能会考虑使用 void* 作为通用参数(将结构指针转换为 void 指针并将其用作函数中的 counter-cast 的参数,该操作无需任何费用)
  • 实现两个构造函数:空构造函数将函数指针初始化为 NULL,而第二个直接分配回调。注意缺少拷贝构造函数,需要自己实现。
  • 实现调用函数的方法(重载运算符 ())并检查回调是否实际存在。

再一次:这些东西编译时没有警告,但我不知道它是否适用于 MSP430,因为我无法测试它(它适用于常见的 amd64 linux系统).

截至 2018 年 2 月,最高支持 C++14,但有一些限制: http://processors.wiki.ti.com/index.php/C%2B%2B_Support_in_TI_Compilers