繁体   English   中英

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

[英]"Illegal hardware instruction" from very simple code

在调查一个可疑的声明时,我编写了这个小测试程序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”得到了加强。 我仍然觉得很难相信。 真的?? 您不能安全地编写自旋循环吗?

所以我想我的问题是:

  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

如果您获得问题中现在代码的 ud2,则编译器不是符合标准的 C 编译器。 您可以报告编译器错误。

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

在 C++ 中,所有线程最终都必须前进,无一例外。 但是在 C 中,控制表达式是常量表达式的循环不需要进行。 我的理解是 C 添加了这个异常,因为在嵌入式编码中使用while(1) {}来挂起线程已经是一种常见的做法。

类似的问题有更详细的答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM