1.cc
struct foo{
const static int bar = 5;
};
int main(){
return foo::bar;
}
2.cc
struct foo{
const static int bar = 6;
};
g++ 1.cc 2.cc
不会给出链接错误。
这是否违反单一定义规则并导致未定义的行为?
此外,我不确定为什么按照本文的建议甚至不需要 const int foo::bar;
:https://www.ibm.com/docs/en/zos/2.1.0?topic=members-static-data
其中说:
Note that the constant initializer is not a definition. You still need to define the static member in an enclosing namespace.
但是我的编译器无论有没有它都可以编译。
最佳答案
你正在破坏One Definition Rule :多个翻译单元中的类定义必须相同。这会使您的程序格式错误,但编译器不必警告您。
如果您有多个定义 ( const int foo::bar;
),您可能会遇到链接器错误。但如果没有任何定义,编译器很难在链接时检测到这一点,所以事实并非如此。
实际上,如果您在1.cc
中有定义,您会发现 1.cc
中的用法总是评估为 5,并且在 2.cc
中有时它们会是6
(在常量表达式中总是 6
),有时是 5
.
您不需要定义即可拥有 return foo::bar;
的原因是这不ODR-use foo::bar
,它只是一个计算结果为 5
的常量表达式(不需要 foo::bar
的定义)。如果你有类似的东西:
int copy(const int& x) {
return x;
}
int main() {
return copy(foo::bar);
}
绑定(bind)引用const int& x
会使用 ODR foo::bar
,链接器会提示没有 foo::bar
的定义.
关于c++ - 如果同一个静态成员变量具有不同的值会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68944476/