Let's say we have a program that is statically linked against MyLib1.0. Also there is a shared library which is linked against MyLib1.1.
Now what happens if the program loads this shared library? My assumption is that during runtime we will have multiple different definitions of the same symbols.
Does both of the following scenarios violates ODR?
Does it matter at all if shared lib is dynamically linked or dynamically loaded?
There are some similar questions but I couldn't find a very clear answer so far.
From the point of view of the ISO C++ standard which defines the "one-definition-rule" there is no concept of static or dynamic linking. There are only translation units.
If your program contains translation units which define the same entity in two different ways (e.g. because the definition changed with version 1.1 of MyLib
), then that is an ODR violation and the program has undefined behavior, irregardless of how you are linking the program.
Everything beyond that is specific to how linking works on the given platform, although of course a lot of it is common behavior, e.g. shared libraries can override symbols and have symbols local to itself.
Compilers have flags and attributes to specify this behavior, e.g. GCC has the -fvisibility
flag and the __attribute__((visbility(/*...*/)))
attribute. Specifing that a symbol is local to the shared library doesn't imply though that it will be compatible when another version is used in the program. For example if the memory layout of a class changed between versions and an object is passed between two parts of the program using the different versions, they are likely to access memory in an incompatible manner, resulting in undefined behavior in the practical sense (rather then the standard's one).
Whether a certain combination of linking different library versions works depends on a lot of factors. So it should only be done if the library author states that this is supported. They need to explicitly take care that changes to the library are binary/ABI-compatible. This is already true when using headers of a different version, not only when actually linking it.