疑わしい主張 の調査中に、この小さなテストプログラムを書きました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++では、例外なく、すべてのスレッドが最終的に進行する必要があります。ただし、Cでは、制御式が定数式であるループが進行する必要はありません。私の理解では、Cがこの例外を追加したのは、組み込みコードでwhile(1) {}
を使用してスレッドをハングアップさせることがすでに一般的な慣習であったためです。