调查时a dubious claim ,我写了这个小测试程序noway.c
int proveit()
{
unsigned int n = 0;
while (1) n++;
return 0;
}
int main()
{
proveit();
return 0;
}
对此进行测试,我得到:
$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction ./a.out
瓦。
如果我在没有优化的情况下进行编译,它会按预期挂起。我查看了程序集,没有所有花里胡哨的 main
函数如下所示:
_main: ## @main
pushq %rbp
movq %rsp, %rbp
ud2
其中ud2
显然是专门针对未定义行为的指令。上述可疑的说法“永不返回的函数是 UB”得到了强化。但我还是觉得很难相信。真的吗!?您无法安全地编写自旋循环吗?
所以我想我的问题是:
- 这是对正在发生的事情的正确解读吗?
- 如果是这样,有人可以向我指出一些可以验证它的官方资源吗?
- 在什么情况下您希望进行此类优化?
相关信息
$ clang --version
Apple clang version 11.0.0 (clang-1100.0.20.17)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
最佳答案
如果您获得问题中现在的代码的 ud2,则该编译器不是符合标准的 C 编译器。您可以报告编译器错误。
请注意,在 C++ 中,此代码实际上是 UB。当添加线程(分别是 C11 和 C++11)时,任何线程都会有前向进度保证,包括非多线程程序的主执行线程。
在 C++ 中,所有线程最终都必须继续进行,无一异常(exception)。然而,在 C 中,控制表达式为常量表达式的循环不需要继续进行。我的理解是 C 添加了这个异常,因为在嵌入式编码中使用 while(1) {}
挂起线程已经是常见的做法。
关于c - "Illegal hardware instruction"来自非常简单的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59080105/