Clang / LLVM 6.0.0不会不要求提供静态数据成员声明的定义。参见以下小程序:
// main.cpp
#include <iostream>
struct A
{
void f()
{
std::cout << "bla";
}
};
struct S
{
static A a; // declaration, not definition
};
int main()
{
S::a.f();
}
此代码成功编译(使用-Xclang -std = c ++ 17 -Xclang -flto -Xclang -O3)并输出“ bla”。但是没有对S :: a的定义。
相比之下,MSVC不会编译,并且会抱怨未解析的外部符号S :: a。
现在这是Clang / LLVM中的错误,对吧?
答案 0 :(得分:2)
basic.def.odr
每个程序应在被丢弃的语句之外,确切地包含该程序中奇特使用的每个非内联函数或变量的一个定义; 无需诊断。
答案 1 :(得分:1)
编译器可能正在将您的代码优化为:
int main()
{
std::cout << "bla";
}
因此,链接器永远不会看到未定义的符号,也不会抱怨。
答案 2 :(得分:0)
是代码未定义的行为,因为您在对象初始化之前访问了对象,它类似于this答案
因为没有初始化就调用膜函数是未定义的行为,编译器可以假定您在某个地方初始化了对象并产生了看到的结果