|
|
|
|
|
by brucedawson
3481 days ago
|
|
The linker could check all .obj files for definitions of the function and see if they match. However this would slow down linking, especially if the linker peeks into .obj files that it otherwise wouldn't examine. It's also not clear what sort of differences to report. Let's say that you have two translation units, one compile /O1 and the other compiled /O2. They would probably generate different versions of floor, but this is not an ODR violation. So, how is the linker supposed to detect when a difference in generated code is fatal and when it is benign? The C++ language does not require reporting of ODR violations because such reporting is expensive and problematic. What sort of ODR reporting do the gcc and clang toolchains do? |
|
With the inline semantics defined by C99 there are two solutions to this problem:
1. Use static inline. Any non-inlined calls will result in an instance of the function with internal linkage. Aside from wasting space with multiple copies of the same function it is harmless. As mentioned, an optimising linker might even merge identical functions across compilation units.
2. Use inline without explicit extern. Non-inlined calls result in an undefined external reference to be resolved by the linker with a definition provided elsewhere. The inline definition is only used when the function is actually inlined and never provides a non-inline definition of the function, internal or external.
Neither of these approaches result in duplicate definitions with external linkage, so the described problem cannot arise.
It's disappointing that Microsoft seem to have chosen the one approach to inline functions that results in this sort of breakage.