Saat menyelidiki klaim yang meragukan , saya menulis program uji kecil ininoway.c
int proveit()
{
unsigned int n = 0;
while (1) n++;
return 0;
}
int main()
{
proveit();
return 0;
}
Menguji ini, saya mendapatkan:
$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction ./a.out
Wat.
Jika saya kompilasi tanpa optimisasi, itu hang seperti yang diharapkan. Saya melihat ke pertemuan, dan tanpa semua lonceng dan peluit, main
fungsinya terlihat seperti ini:
_main: ## @main
pushq %rbp
movq %rsp, %rbp
ud2
Di mana ud2
rupanya adalah instruksi khusus untuk perilaku yang tidak terdefinisi. Klaim meragukan yang disebutkan di atas, "Fungsi yang tidak pernah kembali adalah UB", diperkuat. Saya masih merasa sulit untuk percaya. Betulkah!? Anda tidak dapat dengan aman menulis putaran putaran?
Jadi saya kira pertanyaan saya adalah:
- Apakah ini pembacaan yang benar tentang apa yang sedang terjadi?
- Jika demikian, dapatkah seseorang mengarahkan saya ke sumber daya resmi yang memverifikasinya?
- Apa situasi di mana Anda ingin jenis optimasi terjadi?
Info yang relevan
$ 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
c
standards
undefined-behavior
luqui
sumber
sumber
int n = 0
===>unsigned int n = 0;
atau lebih baik lagi ..while (1);
unsigned int
Jawaban:
Jika Anda mendapatkan ud2 untuk kode yang sekarang ada dalam pertanyaan, maka kompiler bukanlah kompiler C yang sesuai. Anda dapat melaporkan bug kompilator.
Perhatikan bahwa dalam C ++ kode ini sebenarnya adalah UB. Ketika utas ditambahkan (masing-masing C11 dan C ++ 11), ada jaminan kemajuan kemajuan untuk utas apa pun, termasuk utas eksekusi utama dari program yang tidak multi-utas.
Dalam C ++ semua utas akhirnya harus berkembang, tanpa pengecualian. Namun dalam C, loop yang ekspresi pengontrolnya adalah ekspresi konstan tidak diperlukan untuk maju. Pemahaman saya adalah bahwa C menambahkan pengecualian ini karena sudah menjadi praktik yang umum dalam embedded coding untuk menggunakan a
while(1) {}
untuk menggantung utas.Pertanyaan serupa dengan jawaban yang lebih terperinci
sumber
ud2
dari kode C, tapi terima kasih telah menyertakan info tentang C ++ forward progress guarantee (sebuah istilah yang kelihatannya saya akan dapat meneliti) yang sebenarnya saya tanyakan tetapi mendapat, eh, dioptimalkan sebagai Saya sedang mempersiapkan pertanyaan.