Arduino c++11 or c++14 support in platform IO

Hello. I am trying to enable c++14 or at least c++11 support for Arduino development with platformIO, but it seems my toolchain is not set correctly and I do not know how to change it.

I did add

build_flags = -std=c++11

to my platfromio.ini file, but as soon as I include say “functional” the compiler complains:

fatal error: functional: No such file or directory

Processing megaatmega2560 (platform: atmelavr; board: megaatmega2560; framework: arduino)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/megaatmega2560.html
PLATFORM: Atmel AVR 2.2.0 > Arduino Mega or Mega 2560 ATmega2560 (Mega 2560)
HARDWARE: ATMEGA2560 16MHz, 8KB RAM, 248KB Flash
DEBUG: Current (simavr) On-board (simavr)
PACKAGES: 
 - framework-arduino-avr 5.0.0 
 - toolchain-atmelavr 1.50400.190710 (5.4.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf

What am I missing? Thanks for any help you could offer.

The default invocation of GCC is already std=gnu++11. See verbose compilation.

avr-g++ -o .pio\build\megaatmega2560\src\main.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -Os -Wall -ffunction-sections -fdata-sections -flto -mmcu=atmega2560 -DPLATFORMIO=40400 -DARDUINO_AVR_MEGA2560 
-DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -Iinclude -Isrc -IC:\Users\Maxi\.platformio\packages\framework-arduino-avr\cores\arduino -IC:\Users\Maxi\.platformio\packages\framework-arduino-avr\variants\mega src\main.cpp
avr-gcc-ar rc .pio\build\megaatmega2560\libFrameworkArduinoVariant.a

If you want to enable C++14 you will also have to build_unflag that flag.

Hm, I spoke too soon. Even when using the latest available compiler, and the correct C++11, 14 or even 17 flags, AVR-GCC/G++ doesn’t give you the <functional> functionality. Or really, any C++ standard library functionality at all.

[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
build_flags = -std=gnu++17
build_unflags = -std=gnu++11
platform_packages = 
    toolchain-atmelavr@1.70300.191015
#include <Arduino.h>
#include <vector>

void setup() {
    std::vector<int> vec {1,2,3};

}
void loop(){

}

Results in -std=gnu++17 but no implemented C++ standard library

avr-g++ -o .pio\build\megaatmega2560\src\main.cpp.o -c -std=gnu++17 -fno-exceptions -fno-threadsafe-statics -fpermissive -Os -Wall -ffunction-sections -fdata-sections -flto -mmcu=atmega2560 -DPLATFORMIO=40400 -DARDUINO_AVR_MEGA2560 
-DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -Iinclude -Isrc -IC:\Users\Maxi\.platformio\packages\framework-arduino-avr\cores\arduino -IC:\Users\Maxi\.platformio\packages\framework-arduino-avr\variants\mega src\main.cpp
src\main.cpp:2:10: fatal error: vector: No such file or directory
 #include <vector>
          ^~~~~~~~
compilation terminated.

I thought they improved the last time I looked at it, but it still seems to be a wasteland.

Libraries like

suplement the gap here with their own implementations. Though ArduinoSTL seems to also have lacking modern functional support. Using ustd:

[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
; build flags needed by library for identifaction and correct compiling
build_flags= -D __ATMEGA__  -Wno-reorder
; correctly search chained libraries
lib_ldf_mode = chain+
lib_deps = 
    ustd
#include <Arduino.h>
#include "platform.h"
//subfunctionality
#include "array.h"
#include "queue.h"
#include "map.h"
#include "functional.h"

//instead of std::function, use ustd::function
//uncomment this to be able to just use "function" as typename
//using ustd::function;

void print_num(int i)
{
    Serial.println(i);
}

void setup() {
    Serial.begin(115200);
    //create function from function pointer
    ustd::function<void(int)> f_display = print_num;
    f_display(-9);
}

void loop() {
}

that code compiles.

Though it can be of course argued what good it is to use the C++ STL on these constrained devices…

2 Likes

Thanks for that. I was going nuts trying to figure out what am I doing wrong :slight_smile:

Seems it’s back to functors and function pointers for me.

On AVR without additional libraries that seems to be the most compatible way. On other platforms such as ARM, XTensa (ESP8266 + ESP32…), RISCV, … this is much better working and also in use in the Arduino framework and libraries (like here). Only the AVR toolchain, at east the one I’m looking at, is lacking.

1 Like

If you are looking for an alternative, embedded friendly STL like library, then you may be interested in my open source template library on Github.
Embedded Template Library