I've implemented C++ bindings for some C library. The library API calls can fail, but obviously can't throw anything; and my bindings are, for the purposes of this question, all inline.
Now, the compiler can figure out, for most of my inlined functions/methods, that an exception can't be thrown; for example, suppose I have:
bool foo() {
auto result = wrapped_lib_foo();
return some_constexpr_nothrow_cond(result);
}
should I mark such functions/methods with noexcept
?
Notes:
If you throw, your program terminates What happens if you throw from a noexcept function? Your program terminates, and may or may not unwind the stack. Terminating program isn't the nicest way to report an error to your user. You would be surprised that most of C++ code might throw.
In general, you should use noexcept when you think it will actually be useful to do so. Some code will take different paths if is_nothrow_constructible is true for that type. If you're using code that will do that, then feel free to noexcept appropriate constructors.
noexcept (C++) C++11: Specifies whether a function might throw exceptions.
That noexcept keyword is tricky, but just know that if you use it, your coding world will spin faster. The noexcept keyword is a recent addition, so when should you use it? Here's what the guideline says: If your function may not throw, declare it noexcept.
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.
even if wrapped_lib_foo
is a extern "C"
function, the compiler has no way of knowing that somewhere down the stack wrapped_lib_foo
never throws unless you tell it explicitly.
Then there is also that fact that marking the function noexcept
explicitly informs your audience that the function does not throw.
So yes noexcept
is a good idea.
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