【发布时间】:2023-03-28 04:28:01
【问题描述】:
考虑以下代码:
struct X {
static const int i = 45;
};
void foo() {
const int* k = &X::i;
}
int main() {
}
如果不打开您最喜欢的编译器,您认为尝试编译和链接这个简单的野兽会产生什么结果?
有些人可能会感到惊讶,它不仅取决于编译器,还取决于它的优化选项!例如,在 gcc 上,代码将拒绝在优化关闭的情况下链接,但会很乐意在任何优化打开的情况下链接(并生成可运行的无操作可执行文件)。
失败案例中的诊断会很有趣-找不到符号X::i。启用优化的链接会成功,因为X::i 将被丢弃。
还有问题。 编译这段代码是编译器的正确行为吗?由于X::i 没有链接,当被要求生成一个要求该符号链接的代码时,编译器不应该抱怨吗?
【问题讨论】:
-
你是 odr-using
i所以它必须被定义,如果你不这样做就不需要诊断 -
@ShafikYaghmour 我没有看到评论中缺少任何作为答案的内容?
-
@curiousguy 我认为 odr 标签更好,它肯定更具可读性。我投票决定将其设为 odr 标签的同义词。虽然它没有那么旧,但奇怪的是我以前从未注意到它。
-
对于未定义行为的代码没有正确的行为。
-
@M.M NDR 和 UB 并不完全相同,如果我理解正确,NDR 通常是针对编译时问题,而 UB 是针对运行时问题。
标签: c++ compiler-errors language-lawyer one-definition-rule