luq*_*qui 8 c standards undefined-behavior
While investigating a dubious claim, I wrote this little test program noway.c
int proveit()
{
unsigned int n = 0;
while (1) n++;
return 0;
}
int main()
{
proveit();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Testing this, I get:
$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction ./a.out
Run Code Online (Sandbox Code Playgroud)
Wat.
如果我不进行优化就进行编译,则它会按预期挂起。我看了看程序集,没有所有的花哨main功能,函数看起来像这样:
_main: ## @main
pushq %rbp
movq %rsp, %rbp
ud2
Run Code Online (Sandbox Code Playgroud)
其中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
Run Code Online (Sandbox Code Playgroud)
如果您获得问题中现在的代码的 ud2,则该编译器不是符合标准的 C 编译器。您可以报告编译器错误。
请注意,在 C++ 中,此代码实际上是 UB。当添加线程(分别是 C11 和 C++11)时,任何线程都会有前向进度保证,包括非多线程程序的主执行线程。
在 C++ 中,所有线程最终都必须进行,无一例外。然而,在 C 中,控制表达式为常量表达式的循环不需要继续进行。我的理解是,C 添加了这个异常,因为在嵌入式编码中使用 awhile(1) {}来挂起线程已经是常见的做法。