为什么链接器在下面的代码中没有发出错误?

Joã*_*nso 5 c++ one-definition-rule language-lawyer

我在这里找到了这个例子.显然,片段中的注释是错误的,因为变量S::x是由表达式使用的&S::x.

struct S { static const int x = 1; };
void f() { &S::x; } // discarded-value expression does not odr-use S::x
int main(){
    f();
}
Run Code Online (Sandbox Code Playgroud)

查看实例

我理解编译器不需要发出这样的错误,因为[basic.def.odr]/10说"不需要诊断".但是为什么链接器不会发出关于未定义变量的错误S::x,就像在下面的代码中那样?

#include<iostream>
struct S { static const int x = 1; } s;

int main() {
    std::cout << &s.x << '\n';
}  
Run Code Online (Sandbox Code Playgroud)

查看实例.

Kla*_*aus 2

但是为什么链接器不像下面的代码那样发出有关未定义变量 S::x 的错误?

因为它根本就被优化掉了!结果从未被使用且没有副作用的表达式将被简单地忽略。并且不能链接到被忽略的内容。根本没有引用该变量的代码,即使获取了该变量的地址但未使用该变量也是如此。

如您的 wandbox 示例所示,编译器发出正确的诊断:“表达式结果未使用”。

未使用的代码稍后不会导致链接器错误;)

您的第二个示例使用值( var 的地址),因此需要计算表达式。这会向链接器发出代码,在该链接器中在任何地方都找不到地址的符号。