Caution. ODR applies only to definitions that will be included in the final program. This means that this does not apply to characters that may be present in libraries, because the (normal) linker does not load entire libraries, but only those parts that are necessary for character resolution. For example, in this code:
#include <cmath> double log(double) {return 1.0;} int main() { log(1.0); }
No ODR violations:
- either the log symbol from the standard C library was included only in the
std , and there were no collisions at all - or is it also included in the global namespace
In the latter case, the double log(double) declaration does not conflict with that of cmath, because it is the same. And since the log symbol is already defined, its definition from the standard library will not be included in the program. Thus, in the program there is only one definition of the log function, the following: double log(double) {return 1.0;} .
Everything would be different if you extracted an object module containing log from the math library and directly linked it in your program. Since object modules are always included in the resulting program, while object modules in libraries are included only conditionally if they allow undefined characters.
Links from the standard:
The draft n3337 for C ++ 11 or n4296 for C ++ 14 (or n4618 for the latest revision) is explicit in Section 2.2 Translation Phases [lex.phases]:
§9. All references to external entities are permitted. Library components are linked to satisfy external references for objects not defined in the current translation . All such a translator displays an image in the program that contains the information necessary for execution in the runtime environment.
As shown in the code, only one translation unit is used, and log already defined in it, the definition from the library will not be used.
Serge Ballesta Jan 16 '17 at 8:48 2017-01-16 08:48
source share