5 ms·
Interestingly a form the "one definition rule" even applies to some of those functions that can appear in multiple translation units, specifically inline functi
by quietbritishjim 8y ago
Interestingly a form the "one definition rule" even applies to some of those functions that can appear in multiple translation units, specifically inline functions and template functions (not static functions or those in an unnamed namespace). In those case it says that they must be identical in all the translation units that they're defined in, so it's more like a "unique definition rule" for them.
This sounds like it would be easy – just put the definition a header file. But even if the text of a function is identical in different translation units, it can still be ODR-different between them if the symbols that they look up are different due to other header files included before them declaring different thing or doing things like "using namespace std". Argument-dependent lookup is especially dangerous here. As with other ODR violations, this causes undefined behaviour and compilers/linkers aren't required to issue a diagnostic (and they usually don't!). I believe C++20 modules will solve this problem.
- jcelerier 8y ago> this causes undefined behaviour and compilers/linkers aren't required to issue a diagnostic (and they usually don't!) -fsanitize=undefined with LTO has shown ODR violations for a long time
- gpderetta 8y ago> even if the text of a function is identical in different translation units, it can still be ODR-different between them if the symbols that they look up are different due to other header files included before them declaring different thing Exactly. This is why you should never put anonymous namespaces and definitions of objects with static linkage in an header file.
- alexhutcheson 8y agoThe functions can also be different if different compilation units were compiled using different compiler settings (or event different compilers). In Titus Winters' recent Pacific++ talk[1], he pointed out that even something as simple as including an 'assert' statement will violate the ODR if some compilation units are compiled with 'debug' settings and some aren't. This can easily happen with build systems that cache compiled object files if changes in compilations flags don't automatically invalidate the cache. [1] https://youtu.be/IY8tHh2LSX4?t=900 https://youtu.be/IY8tHh2LSX4?t=900