In embedded c++, and especially in real-time systems there is no need to handle exceptions and if a system is going to crash, in common practice, we let it crash. Every crash is a programmer error, that must be fixed. So there is no need to handle exceptions in a release.
Usage of noexcept
specifier can significantly reduce the size of binary files and increase performance. In this way, every stl
function inside a function with noexcept
will call noexcept overload if it is available. But usage of this specifier is restrictive and has a lot of limitations(inheritance, virtual functions signature, compatibility). If you modify source without proper integration, there will be errors like looser throw specifier for...
.
No exception flag(like g++ -fno-exceptions
) only replace all throw
for abort
and may reduce some stack size.
Are there any good practices how to use noexcept
specifier or flags, in the case where it is necessary to upgrade legacy code (before c++11), increase performance and reduce size of binaries? For now, I can see only one way - add noexcept
to every function.
compilers(arm-none-eabi-g++, C++ compiler MSVC), c++14
In this way, every stl function inside a function with
noexcept
will callnoexcept
overload if it is available.
No, because you can't overload on noexcept
. Marking a function with noexcept
doesn't affect overload resolution of functions it calls.
The size reduction from marking a function noexcept
is because the compiler doesn't need to emit code for stack unwinding and exception handling, it can just terminate. But if you use -fno-exceptions
the compiler also doesn't have to emit code for stack unwinding and exception handling, so you should get the same benefits (without needing to add noexcept
anywhere).
Are there any good practices how to use
noexcept
specifier or flags, in the case where it is necessary to upgrade legacy code (before c++11), increase performance and reduce size of binaries?
Good practice is to only add noexcept
to functions that you know definitely can't throw, and which will never be changed to throw, or if you definitely want them to call std::terminate
if an exception does happen.
That doesn't mean adding it to every function.
It also doesn't mean adding it to virtual functions carelessly. Doing so changes the contract of the base class, and requires all overrides to be updated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With