为何odr-used规则在Visual Studio 2015中未触发预期报错?
Let’s start by grounding this in the One Definition Rule (ODR):
通俗来讲,对象被odr-used的情况包括:读取其值(编译时常量除外)或写入、获取其地址,或为其绑定引用;……若对象、引用或函数被odr-used,程序中必须存在其定义;违反此规则通常会导致链接时错误。
若对象被odr-used,则需要在类外部提供定义
In your code, you’re clearly ODR-using A::k: you bind a reference to it (const int& s = A::k) and take its address (&A::k). By strict C++ standards, this requires an out-of-class definition for A::k, like so:
const int A::k;
So why isn’t Visual Studio 2015 throwing a link error or warning?
The answer is a non-standard extension in older MSVC versions. Back in VS2015, the compiler had a convenience feature where it would implicitly generate the definition for static const integral members when they were ODR-used—even if you didn’t write that out-of-class line yourself. This deviated from the standard but saved developers some boilerplate code.
This behavior isn’t universal, though. If you run this same code on a more standards-compliant compiler (like GCC, Clang, or even Visual Studio 2017 and later), you’ll get a link error complaining about an undefined reference to A::k.
To make your code fully standard-compliant and portable across all compilers, just add that out-of-class definition. Even though VS2015 lets you skip it, it’s a good practice to include it.
内容的提问来源于stack exchange,提问作者choxsword

