Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using noexcept and compiler flags that turn off exceptions

Tags:

c++

introduction

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.

problem

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.

question

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

like image 617
Smit Ycyken Avatar asked Mar 07 '23 11:03

Smit Ycyken


1 Answers

In this way, every stl function inside a function with noexcept will call noexcept 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.

like image 173
Jonathan Wakely Avatar answered Apr 30 '23 21:04

Jonathan Wakely