疑わしい主張を調査しながら、私はこの小さなテストプログラムを書きました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
3
IIRC、signed intオーバーフローはUBです。
—
wildplasser
^^^^ ie
—
WhozCraig
int n = 0
===> unsigned int n = 0;
またはそれ以上..while (1);
うーん...コンパイラエクスプローラーのclangは、-O gcc.godbolt.org/z/NTCQYTを使用した自己ターゲットジャンプ命令と、それを使用しない行ごとの変換を取得します。多くのバージョンで一貫しているようです。しかし、C規格では、副作用のない場合の非終端はubであると述べていることも(調べませんが)思い出します。ハンスベームは
—
Gene
未定義の動作は、無限ループではなく、符号付き整数オーバーフローです。次の
—
MM
unsigned int
@Gene言っているとは思いません。const以外の制御式を使用したSideffect-freeループは終了すると想定される場合があります(port70.net/~nsz/c/c11/n1570.html#6.8.5p6)が、ビジーループは問題ないはずです。UD命令では例を再現できませんが、UBは整数オーバーフローにあります。
—
PSkocik