As a rule, exceptions must not propagate module boundaries as for example explained in Herb Sutters C++ Coding Standards (item 62). When compiled with different compilers or just compiler settings this might crash.
I can understand the issue in case e.g. of dynamic link libraries. But I wonder whether it also holds for static libraries. Is a static library a module in the sense of the above rule? If the library is compiled with other compiler settings (e.g. alignment) might the program crash, if an exception is thrown out of the static library and caught in the application?
Generally, a static library has to be compiled by the same compiler and the same compiler settings (mostly) to be compatible with the deliverable (a dynamic library or an executable).
You can, then, throw exceptions outside the boundaries of a static library because it's not much different than a set of .obj files your compiler generated. And you obviously can throw exceptions between different .obj modules.
EDIT:
To sum up the comments:
- You can only use a static library if you're using the same compiler and compiler settings used to compile the library.
- You can throw exceptions between modules compiled with the same compiler and compiler settings.
- From 1) and 2) follows that you can throw exceptions from a static library because, if you're using it, that means you're using the same compiler and compiler settings, hence you can throw exceptions.
Herb Sutters' description is also suitable for static library:
There is no ubiquitous binary standard for C++ exception handling.
Don't allow exceptions to propagate between two pieces of code unless
you control the compiler and compiler options used to build both
sides; otherwise, the modules might not support compatible
implementations for exception propagation. Typically, this boils down
to: Don't let exceptions propagate across module/subsystem boundaries.
It depends on what Herb means by "module". And the issues don't
only concern exceptions; they can concern anything using a C++
interface.
There is certainly no problem when exceptions cross translation
unit boundaries of sources compiled as part of the same
component. Between components, if they are all part of the same
application, and you ensure that they are all compiled using the
same compiler, with the same compiler options, it may be safe,
although there can be problems when crossing between dynamic
libraries, depending on how the libraries are loaded. (In
general, this is only a problem on Unix systems, where the
visibility of symbols in dynamically loaded components is
controlled by the options passed to the dynamic loader.) As
a general rule: arrange to have all of your application compiled
with the same compiler and the same compiler options, and you
should have no real problems within the application (although
you may have to ensure that all dynamic components are
explicitly loaded, at least under Unix). Between
"applications", where you are loading or being loaded by
"foreign" software, Herb's restrictions don't go far enough. In
practice, the interface where you cross between the applications
must be defined in C. And there may still be restrictions,
depending on how your code is loaded and what other dynamically
loaded components are being used.
Linking statically will remove the problems with regards to how
the library is loaded, but changes nothing else.