我在 Instagram 上看到了这个表情包,内容是关于一些 C++ 代码,这些代码不应该输出任何内容,但却会输出任何内容。代码是:
#include <iostream>
int main() {
while (1)
;
}
void unreachable() {
std::cout << "Hello World!" << std::endl;
}
我用 clang 编译了它,如 meme 中所示,并得到了相同的结果 (
Ubuntu clang version 14.0.0-1ubuntu1.1
),但使用 gcc 编译的相同代码执行了你所期望的操作:什么都没有 (g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
)。
我想知道为什么 clang 会做不同的事情,以及如果我从不从主函数调用它,如何破解无法访问的函数是如何执行的。
在
#include <iostream>
int main() {
while (1)
;
}
void unreachable() {
std::cout << "Hello World!" << std::endl;
}
永无休止的无所事事的循环打破了规则。根据 [介绍.进度]
实现可能假设任何线程最终都会执行以下操作之一:
- 终止,
- 调用库 I/O 函数,
- 通过易失性泛左值执行访问,或者
- 执行同步操作或原子操作。
[注 1:这是为了允许编译器进行转换,例如删除空循环,即使无法证明终止也是如此。 — 尾注]
由于程序无效,编译器可以做任何它想做的事情,从生成一个执行您期望的程序(GCC 的响应)到任何其他操作。所以从技术上讲,clang 的结果是有效的。心怀感激。编译器可以选择生成 Skynet。