Is this safe to compile with C++17 for the AVR-GCC compiler?

Hi!

C++17 rocks! However, the different Arduino IDE's are still using C++11. I tweaked the compilation instruction so it was able to compile using C++17, and gracefully it compiled, so good for being true :unamused:

For testing purposes I've compiled this C++17 code:

// (1) Structured binding
// (2) If initializer

struct Res{int x; int y;};

auto foo( int a ) -> Res
{
  return{ a+1, a*2 }; // (1)
}

void setup()
{
  Serial.begin( 9600 );
}

void loop()
{
  auto [a,b] = foo( 5 );  // (1)

  Serial.println( a );
  Serial.println( b );

  if( auto [x,y] = foo( 3 ); x < 10 )  // (2)
  {
    Serial.println( y );
  }
}

An excerpt from the compilation output (just to show it's actually using C++17 and that it compiled):

home/fjrg76/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++17 ...
Generating function prototypes...
...
Compiling sketch...
/home/fjrg76/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -Wall -Wextra -std=gnu++17 ...
Compiling libraries...
Compiling core...
Using precompiled core: /tmp/arduino_cache_911616/core/core_arduino_avr_uno_6da0409820faaaedb6b0232ec4092644.a
Linking everything together...
...
Sketch uses 1736 bytes (5%) of program storage space. Maximum is 32256 bytes.
Global variables use 188 bytes (9%) of dynamic memory, leaving 1860 bytes for local variables. Maximum is 2048 bytes.

C++ compiler version:

$ ./avr-g++ --version
avr-g++ (GCC) 7.3.0
Copyright (C) 2017 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.

$

Is there any issue with this compiler for the ATMEGA328 processor (and alike) that has compelled the Arduino's mainteiners not to use it?

Same thing for Cortex ARM cores: even the Due board is still using C++11. Any reason?

Compiler version for ARM Cortex cores:

$ ./arm-none-eabi-g++ --version
arm-none-eabi-g++ (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824 (release)
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.

$

It's been 6 years from C++17 and right now people is working in the C++23 release, so I think that C++17 is safe enough to be used in embedded systems.

Greetings!

Maybe. I suspect no one knows, and everyone is hesitant to change the C++ version because it would probably require an enormous amount of testing. Also, the AVR gcc compiler being used (and the latest supported by Microchip) is v7.3.0, which only dates back to 2017, so it's support of C++17 might be "weak." (C++ support for AVR in general is weak; I'm pretty sure that Arduino is THE major user. ARM might be in better shape.)

And of course, if you actually use any C++17 features (which ones were you interested in?), you'd cease to be backward compatible with older versions of the IDE.

1 Like

There is a related proposal and discussion here:

3 Likes

Exactly. It seems that most new features are added to the STL, which isn't available on the AVR platform anyway.

EDIT:
Never mind, I see the features noted in OP's code.

1 Like

Although much of C++ guys effort has been put towards the STL, there are interesting C++17 features we can take advantage of, for example:

if/switch with initializations: In the previous code I showed you the "if" part; now let's see the "switch" one:

switch( auto opt=read() ) // initialization inside the switch statement
{
  case 0:
  break;

  case 1:
  [[fallthrough]]; // let the compiler to know that you didn't forget the break
  case 2:
  break;
}

Don't discard the result:
[[nodiscard]] bool if_that(); //

You can see a very good list of features from all recent C++ versions HERE.

Not all STL is about dynamic memory. There exist dynamic-memory free features like touples, std::chrono library, among others, that can be of benefit in embedded systems.

The compiler for the Cortex-M cores (arm-none-eabi-g++) evolves very differently from AVR; however, I guess we'll reach the 2030 year using C++11, and someone will tell "Why are you still using such obsolete compiler?"

Personally, I rather like it when a language remains relatively constant and not everyone jumps on the "fancy new feature" that doesn't really seem to do anything that wasn't possible in the older versions with an extra line of code or two.

And I really dislike having to dig out a language reference to decode all the new syntax, if keeping up with with the new features is "not my thing."

(and most arduino code doesn't use many of the C++11 features. You hardly ever see "auto", for example, even though some people strongly recommend its use.)
(Hmm. Does "auto" inherit all of the type info? For example, if I do:

   auto portPointer = &PORTB;

Does the "volatile" in the definition of PORTB carry over?

1 Like

Concur.

It appears to. Using Eclipse / Sloeber:
image

1 Like

In such sense, C++03 can do much of what C++11 does, but you'd prefered the "fancy" features of it. Even more, we can use C for OOP, but still we're using C++.

It's not about fancyness, it's a way to write better code and that the compiler helps us in doing so. For example, now you can limit the variables scope in an easy and cleanest way:

if( auto r=read(); r < X ){...}

Previous to C++17 one needs to code:

{
  int r=read();
  if( r < X ){...}
}

And it's not about how many lines we save; it's about we can "hide" the control variable in a very convenient way. That's not fancy.

Range-for isn't fancy too; it's a beatiful way for traversing collections, why do we use the "old" for?:

for( auto& e : my_array ){...}

Finally, what about of writing:

delay( 10_s );                  // delay( 10s ) if std::chrono was available for AVRs
auto s = get_speed( 200.0_Km );

instead of:

delay( 10000 );               // 10000 what?
float s = get_speed( 200.0 ); // 200.0 what?

C++ isn't a better C and we should take advantage of it. And as I said, it's been 6 years from C++17, so it's not a new release.

Anyway, thank you for clarify me that Microchip will not update the compiler beyond the 7.3 release, and given that the embedded world is moving towards Cortex-M cores we'll get must of the C++ language through the arm-none-eabi-g++ compiler.

Greetings :slight_smile: !

Eventually you get to the point of Diminishing Returns.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.