非常简单的代码中的“非法硬件指令”

在调查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

Wat。

如果我不进行优化就进行编译,则它会按预期挂起。我看了看一下程序集,没有所有的花哨功能,main函数看起来像这样:

_main:                                  ## @main
    pushq   %rbp
    movq    %rsp,%rbp
    ud2

ud2显然是专门针对未定义行为的指令。前面提到的可疑声明“永不返回的函数是UB”得到了增强。我仍然很难相信。真!?您不能安全地编写自旋循环吗?

所以我想我的问题是:

  1. 这是对正在发生的事情的正确理解吗?
  2. 如果是这样,有人可以指出我的官方资源吗?
  3. 在什么情况下您希望发生这种类型的优化?

相关信息

$ 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
gff138 回答:非常简单的代码中的“非法硬件指令”

如果为问题中的代码获取ud2,则编译器不是合格的C编译器。您可以报告编译器错误。

请注意,在C ++中,此代码实际上是UB。添加线程时(分别为C11和C ++ 11),可以为任何线程(包括非多线程程序的主执行线程)提供前向进度保证。

在C ++中,所有线程都必须最终进展,没有例外。但是,在C语言中,不需要执行其控制表达式为常量表达式的循环。我的理解是C添加了此异常,因为使用while(1) {}挂起线程已经是嵌入式编码中的普遍做法。

Similar question with more detailed answers

本文链接:https://www.f2er.com/3017779.html

大家都在问