Sorry, i meant OP
No hidden magic, just templates for vectors, maps, lists, ... I can't understand why they are not supported on AVR boards. There is no reason they would use more memory than it is necessary.

I can't understand why they are not supported on AVR boards. There is no reason they would use more memory than it is necessary.
I think the question is: who is prepared to maintain the entire C++ standard library for an obsolete 8-bit microcontroller?
Even AVR-libc only has a handful of frequent contributors, there were talks about dropping AVR support from GCC a couple of years back, and Microchip themselves are at least 7 versions of GCC behind for their latest toolchain ...

What does STL do? While it seems to solve my problem I don't like having hidden stuff that magically fixes something without having at least a rough idea what it's doing. 'STL' seems to be hidden magic. Why is this only available on some architectures? I'm guessing that it's not part of standard C++ but something that's been built with and added to C++.
In the STL, memory allocation failures use try-catch to throw exceptions like std::bad_alloc, which increases memory usage due to the additional stack space and larger binary size required for exception handling.
This dynamic memory management also risks fragmentation in systems with limited resources, like AVR microcontrollers.
There is also dependency on iterators which themselves are lightweight and don’t significantly contribute to code size, but their use with dynamic containers can increase binary size, especially when exception handling is enabled.
Disabling exceptions reduces memory overhead but removes automatic error handling for allocation failures. We see from time to time how the String class wreaks havoc either because calls silently fails when not crashing the arduino or due to fragmented heap.
My guess is that the Arduino team assessed the risk/value of having better C++ features versus code failure for beginners and artists who would have no clue about what’s happening under the hood.
Side note : GCC implements try-catch by generating code that sets up a catch table when entering a try block, which contains information about catch handlers. If an exception is thrown, the stack unwinding process deallocates resources and calls destructors for stack objects while searching the catch table for a matching handler. This mechanism increases memory usage due to the additional metadata required for exception handling and the overhead associated with stack manipulation.
I'm not clear if you are saying that any use of the STL risks problems with memory management or exception handling or if only some features (is that the correct term) carry that risk.
Does the code presented by @gfvalvo carry that risk?
I suspect that the way stack or heap fragmentation is usually presented on the forum is wrong, but I don't have enough knowledge to back up my suspicion. However, this is my topic so...
Usually it is stated that Strings can crash code on microcontrollers with only a small amount of RAM because the heap grows until it crashes into something else. The suggestion is that it won't happen on devices with a lot more RAM. Clearly it doesn't matter how much RAM there is, if the heap keeps growing then sooner or later it will hit other things in RAM, having more RAM just delays the inevitable.
The other thing that doesn't get discussed is the mechanism for program crash on a machine with a Harvard architecture. No amount of RAM corruption affects the program code because they exist in separate memory.
I was trying to give an example with containers on why the STL is not part of the configuration for AVRs.
Some features used in the underlying classes rely on specific C++ features that are memory hungry.

Does the code presented by @gfvalvo carry that risk
Underneath std::function
, there is something known as type erasure — which allows it to store any callable object (like a lambda, functor, or function pointer) that matches a specific signature without needing to know the exact type at compile time.
It's done by defining a common base class that encapsulates the call operation and storing the callable in a derived class that implements this interface. This mechanism enables std::function
to be versatile but also comes with trade-offs in memory and performance as @gfvalvo said. So if you have spare RAM, that's OK but on a UNO...

GCC implements try-catch by generating code that sets up a catch table when entering a try block, which contains information about catch handlers. If an exception is thrown, the stack unwinding process deallocates resources and calls destructors for stack objects while searching the catch table for a matching handler. This mechanism increases memory usage due to the additional metadata required for exception handling and the overhead associated with stack manipulation.
It is worth noting that this is a disadvantage of the current implementation used by GCC, and not a fundamental problem of exceptions. If implemented properly, using exceptions for error handling actually has a lower memory footprint than using manual error handling using return codes and if statements: https://www.youtube.com/watch?v=BGmzMuSDt-Y

What does STL do? While it seems to solve my problem I don't like having hidden stuff that magically fixes something without having at least a rough idea what it's doing. 'STL' seems to be hidden magic. Why is this only available on some architectures? I'm guessing that it's not part of standard C++ but something that's been built with and added to C++.
The STL is a C++ library that was developed by Alexander Stepanov in the early 90s that laid the foundation for generic programming in C++. It was a big deal, and many of its core principles made it into the C++ standard library, and some people still incorrectly refer to the C++ standard library as the STL.
std::function
is part of the C++ standard library, not the STL. The C++ standard library is an integral part of the C++ language, as the name implies, and some language features cannot be used at all without the standard library. However, there is no implementation of the C++ standard library for the AVR platform. As discussed in my previous post, the reason for this is mainly economic, not technical.
The lack of the standard library is one of the main reasons why I no longer bother with AVR-based Arduinos for personal projects. Besides, many ARM chips are cheaper and more powerful anyway.

The other thing that doesn't get discussed is the mechanism for program crash on a machine with a Harvard architecture. No amount of RAM corruption affects the program code because they exist in separate memory.
Overwriting program code is not the issue here. If your heap crashes into the stack, it's over, regardless of whether it's a Harvard or a von Neumann machine. The stack contains local variables and return addresses. Overwrite the local variables, and you'll end up with invalid indices, pointers etc., which will likely cause a crash, and if you overwrite the return address, you'll jump to some random address, also crashing the system.

Does the code presented by @gfvalvo carry that risk?
It depends on the size of the small buffer in the implementation of std::function
. If your function object is small enough, no dynamic allocation takes place, and the data is stored inside of the std::function
object itself. IIRC, the small buffer usually isn't much larger than one pointer, though.

I'm not clear if you are saying that any use of the STL risks problems with memory management or exception handling or if only some features (is that the correct term) carry that risk.
Only some features. If you use something like std::vector
or std::string
, that will obviously involve dynamic memory, whereas many other features like std::array
or std::numeric_limits
are perfectly safe.
The main problem with throwing and not catching the exceptions is that they restart the controller. By not being able to catch and properly handle the exceptions inside your code the controller will restart each time it runs out of memory.
If this isn't the case for a particular Arduino sketch and controller you are pretty much on the safe side by using STL classes.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.