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

930 views Asked by At

I'm writing some code that would greatly benefit from the concise syntax of lambdas, which were introduced with C++ 11. Is this supported by the compiler?

How do I specify the compiler flags when compiling using Energia or embedXcode?

2

There are 2 answers

2
Matteo Ragni On BEST ANSWER

There isn't much about this topic on the TI site, or, at least, I don't know enough C++ to give you a detailed and precise response.

The implementation of the embedded ABI is described in this document that is mainly a derivation of the Itanium C++ ABI. It explains nothing about the implementation of lambdas nor the auto, keyword (or probably I'm not able to derive this information from the documentation).

Thus I decided to directly test in Energia. Apparently the g++ version is 4.6.3, thus it should support both.

And in fact (from a compilation point of view, I don't have my MSP here to test the code) it can compile something like:

// 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() { }    

(the template works only if in an header, in the main sketch raises an error). To compile this sketch I had to modify one internal file of the editor. The maximum supported standard seems to be -std=c++0x, and the compilation flags are in the file:

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

in my setup the root is in /opt/energia. Inside that file I modified line 32 (compiler.cpp.flags) and added the option. Notice that -std=c++11 is not supported (raises an error).

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

Unfortunately I have zero experience with embedXcode :\

Mimic std::function

std::function is not provided, thus you have to write some sort of class that mimics it. Something like:

// 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() {}

may do the work, and it uses a simple trick:

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]

As soon as you leave the capture empty, you are assured to have a "conversion" to a function pointer, thus you can store it without issues. The code I have written:

  • requires a first template RET that is the returned type
  • requires a second template ARG that is one argument for the callback. In the majority of the case you may consider to use void* as common argument (cast a struct pointer in a void pointer and use it as argument, to counter-cast in the function, the operation costs nothing)
  • implements two constructors: the empty constructor initialize the function pointer to NULL, while the second directly assigns the callback. Notice that the copy constructor is missing, you need to implement it.
  • implements a method to call the function (overloading the operator ()) and to check if the callback actually exists.

Again: this stuff compiles with no warnings, but I don't know if it works on the MSP430, since I cannot test it (it works on a common amd64 linux system).

0
Kris On

As of February 2018, up to C++14 is supported with some limitations: http://processors.wiki.ti.com/index.php/C%2B%2B_Support_in_TI_Compilers