What does C++ standard say about dynamic libraries? I heard that it completely ignores them (for some reason) - if it's true, why so?
There are, effectively, just 2 major pitfalls with dynamic libraries, where you can trivially break the assumptions made in the C++ Standard such that it doesn't match the abstract machine:
Violating the "One Definition" rule: e.g., you have managed to dynamically link two libraries with different implementations of the same symbol; each one has, for some reason, preferred local linkage and, depending on who calls, a different implementation is used. The C++ spec still tells you what you are allowed to do, even though the compiler, linker and dynamic loader can be easily configured to violate that rule.
In this case, the default you have, e.g., on Linux systems with ld-linux + gcc + ld
, with public visibility for all symbols, means that all symbols are resolved by the dynamic loader at runtime, which actually fits the description of the abstract machine.
Unfortunately this default is not preferable at all, for performance reasons. Limiting visibility of symbols is the prerequisite to allow even the most basic forms of inlining optimizations.
Loading and unloading libraries at unexpected times: This means pointers (to code and data segments) can become (or remain) invalid at arbitrary times, which doesn't match the abstract state machine at all.
In both cases, it's still your responsibility as a developer to ensure that you stay within the bounds of the abstract machine, and not cause any observable behavior which would contradict it.
So much for the theory.
The reality is that, in both cases, most dynamic libraries actually don't even try to act as if the system/process as a whole was compliant with the C++ abstract machine.
Instead, C++ is only expected to be fully functional within each dynamic library, while the entire external interface is entirely aware of dynamic linkage, symbol visibility etc., and avoids any C++ features which could potentially expose undefined behavior on the boundaries. Each library – on its own – acts in compliance with the abstract machine.