PlatformIO Community

Unable to use C++17 Structured bindings despite enabling standard

I’ve been trying to use c++17 structured bindings in an arduino project, however it doesn’t compile.
I have set build_flags and build_unflags.

However the even weirder problem is this.
I did pio run with the verbose flag.
And i ran the command used compile the unit seperately. It compiled the unit successfully. So it is some platformio enviorment variable thats causing the problem.

Does avr-gcc even support this feature? I wasn’t to check this with some googling.

Thanks for taking a look at this.

I tried adding an ‘advanced scripting’ to dump the env.

Import("env")

# access to global construction environment
print(env)

# Dump construction environment (for debug purpose)
print(env.Dump())

But i didnt find anything that seemed useful.
Full dump here: as a comment

Architecture:

OS: Arch Linux x86_64
Host: Swift SF315-52 V1.07
Kernel: 5.8.14-arch1-1


% avr-g++ --version
avr-g++ (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

% pio --version
PlatformIO, version 5.0.1

% cat platformio.ini
[platformio]

[env]
platform = atmelavr
board = megaatmega2560
framework = arduino
src_filter = +<*.cpp> +<*.cc> +<*.c> -<mains/*>

[env:struct_bind_test]
src_filter = -<*> +<mains/struct_binding_test.cc>
build_unflags =
    -std=gnu++11

build_flags =
    -std=c++17
    -std=gnu++17

% cat ./src/mains/struct_binding_test.cc
#include <Arduino.h>

struct ret_type {
    bool a;
    unsigned long b;
};

ret_type get_val() {
    return {true, 100};
}

void setup() {}

void loop() {
    auto[x, y] = get_val();

}

– div ----

% pio run -e "struct_bind_test"
Processing struct_bind_test (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
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 5 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio/build/struct_bind_test/src/mains/struct_binding_test.cc.o
src/mains/struct_binding_test.cc: In function 'void loop()':
src/mains/struct_binding_test.cc:15:9: error: expected unqualified-id before '[' token
     auto[x, y] = get_val();
         ^
Compiling [.pio/build/struct_bind_test/src/mains/struct_binding_test.cc.o] Error 1
====================================== [FAILED] Took 0.54 seconds ======================================

Environment       Status    Duration
----------------  --------  ------------
struct_bind_test  FAILED    00:00:00.539
================================= 1 failed, 0 succeeded in 00:00:00.539 =================================
% pio run -e "struct_bind_test" -v
Processing struct_bind_test (src_filter: -<*> +<mains/struct_binding_test.cc>; build_unflags: -std=gnu++11; build_flags: -std=c++17, -std=gnu++17; platform: atmelavr; board: megaatmega2560; framework: arduino)
---------------------------------------------------------------------------------------------------------
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
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 5 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
avr-g++ -o .pio/build/struct_bind_test/src/mains/struct_binding_test.cc.o -c -std=c++17 -std=gnu++17 -fno-exceptions -fno-threadsafe-statics -fpermissive -Os -Wall -ffunction-sections -fdata-sections -flto -mmcu=atmega2560 -DPLATFORMIO=50001 -DARDUINO_AVR_MEGA2560 -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -Iinclude -Isrc -I~/.platformio/packages/framework-arduino-avr/cores/arduino -I~/.platformio/packages/framework-arduino-avr/variants/mega src/mains/struct_binding_test.cc

~/.platformio/packages/framework-arduisrc/mains/struct_binding_test.cc: In function 'void loop()':
src/mains/struct_binding_test.cc:15:9: error: expected unqualified-id before '[' token
n     auto[x, y] = get_val();
         ^
====================================== [FAILED] Took 0.54 seconds ======================================

Environment         Status    Duration
------------------  --------  ------------
steer_p             IGNORED
remote_control      IGNORED
serial_passthrough  IGNORED
http_server         IGNORED
AT_rewrite          IGNORED
struct_bind_test    FAILED    00:00:00.538
================================= 1 failed, 0 succeeded in 00:00:00.538 =================================

% avr-g++ -o .pio/build/struct_bind_test/src/mains/struct_binding_test.cc.o -c -std=c++17 -std=gnu++17 -fno-exceptions -fno-threadsafe-statics -fpermissive -Os -Wall -ffunction-sections -fdata-sections -flto -mmcu=atmega2560 -DPLATFORMIO=50001 -DARDUINO_AVR_MEGA2560 -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -Iinclude -Isrc -I~/.platformio/packages/framework-arduino-avr/cores/arduino -I~/.platformio/packages/framework-arduino-avr/variants/mega src/mains/struct_binding_test.cc
src/mains/struct_binding_test.cc: In function 'void loop()':
src/mains/struct_binding_test.cc:15:9: warning: structured binding declaration set but not used [-Wunused-but-set-variable]
   15 |     auto[x, y] = get_val();
      |         ^~~~~~
%

Env dump: https://pastebin.com/Fxy1jfaX

Your local avr-g++ version may well be 10.2.0, but PIO will only use tools from its registry and those which are set by the platform’s (atmelavr) settings. Which is

5.4.0.

Available GCC versions are listed in https://bintray.com/platformio/tool-packages/toolchain-atmelavr-linux_x86_64#files. This goes up to 7.3.0. Toolchain versions are selectible using platform_packages directives.

However, as AVR-GCC is generally lacking in C++ features, you should do a sanity check first.

Compile the file test.cpp

struct ret_type {
    bool a;
    unsigned long b;
};

ret_type get_val() {
    return {true, 100};
}


int main() {
    auto[x, y] = get_val();
    return 0; 
}

with your latest-greatest avr-g++ using

avr-g++ -o test.o -std=c++17 -c test.cpp

If that AVR-G++ version is not able to create an object file, 7.3.0 also definitely won’t. In that case, going to AVR-GCC people (their maillist) would be the way to go.

1 Like

Thank you this solved the problem.
platform_packages = toolchain-atmelavr@>1.7
Brought in avr-gcc 7.30.

I did not know that platformio used a seperate set of packages.