`std=gnu++20` is shown as `201709`? @ NodeMCU:ESP8266:Arduino

I’ve decided to upgrade my C++ standard from the default C++17 to a newer C++20.

[env:nodemcu]
platform = espressif8266
board = nodemcuv2
framework = arduino

build_unflags =
    -std=gnu++17

build_flags =
    -std=gnu++20

std::span wasn’t working before → now it is. Nice. I can assume v20 is working.

BUT, the strange thing, when I print the standard version to the serial monitor, it is showing… 201709 o.O

struct Build final {
    const char* const gitCommitHash;
    const char* const date = __DATE__;
    const char* const time = __TIME__;
    const struct Compiler final {
        const long standard = __cplusplus;
#ifdef __clang__
        const char* const name = "CLANG";
        int versionMajor = __clang_major__;
        int versionMinor = __clang_minor__;
        int versionPatchLevel = __clang_patchlevel__;
#else
        const char* const name = "GCC";
        int versionMajor = __GNUC__;
        int versionMinor = __GNUC_MINOR__;
        int versionPatchLevel = __GNUC_PATCHLEVEL__;
#endif
    } compiler;
};
13:49:09.985 >   Built: Mar 10 2023 @ 13:32:04 @ 6f6563e
13:49:09.986 >          GCC 10.3.0 @ 201709

So, it looks like __cplusplus is showing a wrong standard version?

pio run -e nodemcu -v is showing for example this:

xtensa-lx106-elf-g++ -o .pio/build/nodemcu/libc46/ESPAsyncTCP/ESPAsyncTCP.cpp.o -c -std=gnu++20 -fno-rtti -fno-exceptions -Wall -Os -mlongcalls -mtext-section-literals -falign-functions=4 -U__STRICT_ANSI__ -D_GNU_SOURCE -ffunction-sections -fdata-sections -Wall -Werror=return-type -free -fipa-pta -DPLATFORMIO=60106 -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_NODEMCU_ESP12E -DBUILD_GIT_COMMIT_HASH=\"19fe800\" -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DARDUINO=10805 -DARDUINO_BOARD=\"PLATFORMIO_NODEMCUV2\" -DFLASHMODE_DIO -DLWIP_OPEN_SRC -DNONOSDK22x_190703=1 -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 -DVTABLES_IN_FLASH -DMMU_IRAM_SIZE=0x8000 -DMMU_ICACHE_SIZE=0x8000 -I.pio/libdeps/nodemcu/ESPAsyncTCP/src -I/Users/dada/.platformio/packages/framework-arduinoespressif8266/tools/sdk/include -I/Users/dada/.platformio/packages/framework-arduinoespressif8266/cores/esp8266 -I/Users/dada/.platformio/packages/toolchain-xtensa/include -I/Users/dada/.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip2/include -I/Users/dada/.platformio/packages/framework-arduinoespressif8266/variants/nodemcu .pio/libdeps/nodemcu/ESPAsyncTCP/src/ESPAsyncTCP.cpp

As you can see, -std=gnu++20 is being applied. Well, span is working, so I already knew that.

~/.platformio/packages/toolchain-xtensa/bin/xtensa-lx106-elf-g++ -v            
Using built-in specs.
COLLECT_GCC=/Users/dada/.platformio/packages/toolchain-xtensa/bin/xtensa-lx106-elf-g++
COLLECT_LTO_WRAPPER=/Users/dada/.platformio/packages/toolchain-xtensa/bin/../libexec/gcc/xtensa-lx106-elf/10.3.0/lto-wrapper
Target: xtensa-lx106-elf
Configured with: /workdir/repo/gcc-gnu/configure --prefix=/workdir/xtensa-lx106-elf.osx --build=x86_64-linux-gnu --host=x86_64-apple-darwin14 --target=xtensa-lx106-elf --disable-shared --with-newlib --enable-threads=no --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --disable-nls --disable-multilib --disable-bootstrap --enable-languages=c,c++ --enable-lto --enable-static=yes --disable-libstdcxx-verbose
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 10.3.0 (GCC) 

GCC version seams to be correct → so, it is just __cplusplus showing a wrong info?

When I do

C:\Users\Max\.platformio\packages\toolchain-xtensa\bin\xtensa-lx106-elf-g++.exe  -v --help

I get

  -std=gnu++17                Conform to the ISO 2017 C++ standard with GNU
                              extensions.
  -std=gnu++1y                Deprecated in favor of -std=gnu++14.  Same as
                              -std=gnu++14.
  -std=gnu++1z                Deprecated in favor of -std=gnu++17.  Same as
                              -std=gnu++17.
  -std=gnu++20                Conform to the ISO 2020 C++ draft standard with
                              GNU extensions (experimental and incomplete
                              support).  Same as -std=gnu++2a.
  -std=gnu++2a                Conform to the ISO 2020 C++ draft standard with
                              GNU extensions (experimental and incomplete
                              support).

And further

C:\Users\Max\.platformio\packages\toolchain-xtensa\bin\xtensa-lx106-elf-g++.exe -std=gnu++20 -dM -E -x c++  - < NUL

gives

#define __cplusplus 201709L

So that version of the compiler definitely set the the __cplusplus macro to the the C++ 17 standard one. Likely because of the above warning that support is incomplete and experimental.

1 Like

Plus, I’m not aware of a ESP8266 XTensa toolchain newer than 10.3.0. The Arduino-ESP8266 core uses the toolchain from

which is of that version. The official ESP8266 RTOS toolchain is even more behind at 8.4.0.

https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/get-started/windows-setup.html

1 Like

This explains it, thanks!