Diperbarui, lihat di bawah!
Saya telah mendengar dan membaca bahwa C ++ 0x memungkinkan kompiler untuk mencetak "Halo" untuk cuplikan berikut
#include <iostream>
int main() {
while(1)
;
std::cout << "Hello" << std::endl;
}
Tampaknya ada hubungannya dengan utas dan kemampuan pengoptimalan. Sepertinya bagi saya ini bisa mengejutkan banyak orang.
Apakah seseorang memiliki penjelasan yang baik tentang mengapa ini perlu untuk memungkinkan? Untuk referensi, konsep C ++ 0x terbaru mengatakan di6.5/5
Sebuah loop itu, di luar pernyataan-for-init dalam kasus pernyataan for,
- tidak membuat panggilan ke fungsi I / O perpustakaan, dan
- tidak mengakses atau memodifikasi objek yang mudah menguap, dan
- tidak melakukan operasi sinkronisasi (1.10) atau operasi atom (Ayat 29)
dapat diasumsikan oleh implementasi untuk mengakhiri. [Catatan: Ini dimaksudkan untuk memungkinkan transformasi compiler, seperti penghapusan loop kosong, bahkan ketika penghentian tidak dapat dibuktikan. - catatan akhir]
Edit:
Artikel berwawasan ini mengatakan tentang teks Standar itu
Sayangnya, kata-kata "perilaku tidak terdefinisi" tidak digunakan. Namun, kapan saja standar mengatakan "kompiler dapat mengasumsikan P," tersirat bahwa sebuah program yang memiliki properti bukan-P memiliki semantik yang tidak ditentukan.
Apakah itu benar, dan apakah kompiler diperbolehkan untuk mencetak "Sampai jumpa" untuk program di atas?
Ada utas yang lebih mendalam di sini , yaitu tentang perubahan analog ke C, dimulai oleh Guy melakukan artikel terkait di atas. Di antara fakta berguna lainnya, mereka menghadirkan solusi yang tampaknya juga berlaku untuk C ++ 0x ( Pembaruan : Ini tidak akan berfungsi lagi dengan n3225 - lihat di bawah!)
endless:
goto endless;
Tampaknya kompiler tidak diizinkan untuk mengoptimalkannya, karena itu bukan loop, tetapi lompatan. Seorang pria lain merangkum perubahan yang diusulkan dalam C ++ 0x dan C201X
Dengan menulis loop, programmer menyatakan baik bahwa loop melakukan sesuatu dengan perilaku yang terlihat (Melakukan I / O, mengakses objek yang mudah menguap, atau melakukan suatu sinkronisasi atau operasi atom), atau yang akhirnya berakhir. Jika saya melanggar asumsi itu dengan menulis infinite loop tanpa efek samping, saya berbohong kepada kompiler, dan perilaku program saya tidak terdefinisi. (Jika saya beruntung, kompiler mungkin memperingatkan saya tentang hal itu.) Bahasa tidak memberikan (tidak lagi menyediakan?) Cara untuk mengekspresikan loop tanpa batas tanpa perilaku yang terlihat.
Perbarui pada 3.1.2011 dengan n3225: Komite memindahkan teks ke 1.10 / 24 dan berkata
Implementasi dapat berasumsi bahwa utas pada akhirnya akan melakukan salah satu dari yang berikut:
- mengakhiri,
- melakukan panggilan ke fungsi I / O perpustakaan,
- mengakses atau memodifikasi objek yang mudah menguap, atau
- melakukan operasi sinkronisasi atau operasi atom.
The goto
Trik akan tidak bekerja lagi!
int x = 1; for(int i = 0; i < 10; ++i) do_something(&i); x++;
menjadi for(int i = 0; i < 10; ++i) do_something(&i); int x = 2;
? Atau mungkin sebaliknya, dengan x
diinisialisasi 2
sebelum loop. Bisa do_something
dikatakan tidak peduli tentang nilai x
, jadi itu optimasi yang sangat aman, jika do_something
tidak menyebabkan nilai i
berubah sehingga Anda berakhir di loop tak terbatas.
main() { start_daemon_thread(); while(1) { sleep(1000); } }
mungkin langsung keluar daripada menjalankan daemon saya di utas latar?
while(1) { MyMysteriousFunction(); }
harus dapat dikompilasi secara independen tanpa mengetahui definisi fungsi misterius itu, kan? Jadi bagaimana kita bisa menentukan apakah itu membuat panggilan ke fungsi I / O perpustakaan? Dengan kata lain: pasti bahwa peluru pertama dapat diutarakan tidak membuat panggilan ke fungsi .