Güncellenmiş, aşağıya bakın!
Duydum ve C ++ 0x derleyicinin aşağıdaki snippet için "Merhaba" yazdırmasına izin verdiğini okudum
#include <iostream>
int main() {
while(1)
;
std::cout << "Hello" << std::endl;
}
Görünüşe göre iş parçacıkları ve optimizasyon yetenekleri ile ilgili bir şey var. Bana öyle geliyor ki, bu birçok insanı şaşırtabilir.
Birinin bunun neden izin vermesi gerektiğine dair iyi bir açıklaması var mı? Başvuru için, en son C ++ 0x taslağı6.5/5
For ifadesi için for-init-ifadesinin dışında bir döngü,
- kütüphane G / Ç işlevlerine çağrı yapmaz ve
- geçici nesnelere erişmez veya bunları değiştirmez ve
- senkronizasyon işlemi (1.10) veya atomik işlem gerçekleştirmez (Madde 29)
uygulama tarafından feshedileceği varsayılabilir. [Not: Bu, sonlandırma kanıtlanamamış olsa bile, boş döngülerin kaldırılması gibi derleyici dönüşümlerine izin vermek için tasarlanmıştır. - son not]
Düzenle:
Bu anlayışlı makalede , Standartlar metni hakkında
Ne yazık ki, "tanımsız davranış" kelimeleri kullanılmıyor. Bununla birlikte, standart "derleyici P'yi kabul edebilir" dediğinde, P olmayan özelliğine sahip bir programın tanımsız semantik olduğu ima edilir.
Bu doğru mu ve derleyicinin yukarıdaki program için "Bye" yazmasına izin veriliyor mu?
Burada , yukarıda bağlantılı makaleyi yapan Guy tarafından başlatılan, C'ye benzer bir değişiklikle ilgili daha da anlaşılır bir konu var . Diğer yararlı gerçeklerin yanı sıra, C ++ 0x için de geçerli görünen bir çözüm sunuyorlar ( Güncelleme : Bu, n3225 ile artık çalışmaz - aşağıya bakın!)
endless:
goto endless;
Bir derleyicinin bunu optimize etmesine izin verilmiyor, öyle görünüyor, çünkü bir döngü değil, bir sıçrama. Başka bir adam C ++ 0x ve C201X'te önerilen değişikliği özetliyor
Bir döngü yazarak, programcı iddiasında ya döngü görünür davranışı ile bir şey (gerçekleştirir I / O kere uçucu nesneleri veya yapar senkronizasyonu veya atom işlemleri) yapar, ya da en sonunda son bulan. Yan etkisi olmayan sonsuz bir döngü yazarak bu varsayımı ihlal edersem derleyiciye yalan söylüyorum ve programımın davranışı tanımsız. (Şanslıysam, derleyici beni bu konuda uyarabilir.) Dil, görünür davranış olmadan sonsuz bir döngü ifade etmenin bir yolunu (artık sağlamaz mı?) Sağlamaz.
3.1.2011'de n3225 ile güncelleme: Komite metni 1.10 / 24'e taşıdı ve
Uygulama, herhangi bir iş parçacığının sonunda aşağıdakilerden birini yapacağını varsayabilir:
- sonlandırmak
- kütüphane G / Ç işlevini arama,
- geçici bir nesneye erişme veya bu nesneyi değiştirme veya
- bir senkronizasyon işlemi veya bir atomik işlem gerçekleştirin.
goto
Hüner olacak değil artık işe!
int x = 1; for(int i = 0; i < 10; ++i) do_something(&i); x++;
içine for(int i = 0; i < 10; ++i) do_something(&i); int x = 2;
? Ya da muhtemelen başka bir yolla, döngüden önce x
başlatılırken 2
. Bu söyleyebilir do_something
değeri umursamayan x
onun a tamamen güvenli optimizasyon yüzden, eğer do_something
neden olmaz değerinin i
Eğer sonsuz döngüye sonunda böyle değiştirmek için.
main() { start_daemon_thread(); while(1) { sleep(1000); } }
, arka plan iş parçacığında daemon'umu çalıştırmak yerine hemen çıkabileceği anlamına mı geliyor?
while(1) { MyMysteriousFunction(); }
bu gizemli işlevin tanımını bilmeden bağımsız olarak derlenebilir olmalı, değil mi? Peki herhangi bir kütüphane G / Ç işlevine çağrı yapıp yapmadığını nasıl belirleyebiliriz? Başka bir deyişle: kesinlikle ilk merminin ifade edilebileceği fonksiyonlara çağrı yapmaz .