I think this is good practice to add "noexcept", when you know a function doesn't throw. It is because a C function can throw, if it calls back into C++.
Whether this calling back to C++ and throw is allowed, seems to be compiler dependent. I've checked two compilers:
MSVC: has an option, /EHs
, which:
The exception-handling model that catches C++ exceptions only and
tells the compiler to assume that functions declared as extern "C" may
throw an exception.
So, if this option is specified, then the compiler assumes that a C function can throw.
GCC: here's the documentation of -fexceptions
:
Enable exception handling. Generates extra code needed to propagate
exceptions. For some targets, this implies GCC generates frame unwind
information for all functions, which can produce significant data size
overhead, although it does not affect execution. If you do not specify
this option, GCC enables it by default for languages like C++ that
normally require exception handling, and disables it for languages
like C that do not normally require it. However, you may need to
enable this option when compiling C code that needs to interoperate
properly with exception handlers written in C++. You may also wish to
disable this option if you are compiling older C++ programs that don’t
use exception handling.
So, this implies that with -fexceptions
, GCC compiles C code which can throw. Note, however: when calling a C function, the compiler doesn't know, whether the C code was compiled with -fexceptions
, or not. So it has to assume, that it was. So, it seems that GCC must assume, that a C code can throw (the other possible way could be that -fexception
would need to be specified for C++ code for telling the compiler that a called C code can throw, but doc of -fexceptions
doesn't say anything like this).
Note: for GCC, throwing from a call stack, where a C function is involved, works even without the C code compiled with -fexceptions
currently.