You are squarely into "undefined behavior" territory here:
static int throw314() { std::cout << "throw314() called\n" << std::flush; throw 3.14f; } static int throwDuringInitialization = throw314();
You are throwing from a constructor. That's STRONGLY discouraged - it leads to undefined behavior, as you cannot tell how much of an object has been constructed, and thus how much can be safely torn down. It's far better to have a function to be called after the constructor has completed, and let that function throw if needed, so that you can be sure all objects are fully constructed (and thus can be destructed) before the exception can cause problems.
int main() { try { void* handle = dlopen("throw_in_static_init.so", RTLD_LAZY); std::cout << "Lib loading: " << (handle ? "successfull" : "failed") << "\n"; } catch (float f) { std::cout << "Exception caught in main function: " << f << std::endl; }
It's also a really bad idea to throw an exception from within a C function (dlopen). Ideally, any function with extern "C" linkage should avoid any C++ specific concepts, like exceptions. The compiler won't have done all the homework in dlopen for things like unwinding the stack in an exception, since exceptions don't exist in C.
If you need your shared library to do some initialization that potentially could fail, you should probably define a C++ function within the shared library that does the exception, and will be called after the dlopen completes successfully.
I suggest you get the Scott Meyer books "Effective C++" and “More Effective C++” and read them thoroughly.
Attachment:
OpenPGP_0x5B9DC79986207D69.asc
Description: application/pgp-keys
Attachment:
OpenPGP_signature
Description: OpenPGP digital signature