SORU
18 NİSAN 2014, Cuma


Tanımsız davranış ile dalları ulaşılamaz kabul ve ölü kod olarak optimize edilebilir?

Düşünün aşağıdaki beyanı:

*((char*)NULL) = 0; //undefined behavior

Açıkça tanımlanmamış bir davranışa çağırır. Belirli bir programda böyle bir açıklama varlığını tüm program tanımlı değil ya da bu davranış, yalnızca kontrol akışı bu deyimi şarkıları bir kez tanımsız olur anlamına mı geliyor?

Aşağıdaki program kullanıcı asla 6 ** numarasını girer diye iyi tanımlanmış olurdu?

while (true) {
 int num = ReadNumberFromConsole();
 if (num == 3)
  *((char*)NULL) = 0; //undefined behavior
}

Veya tamamen tanımsız davranış, kullanıcı girerse ne olur?

Ayrıca, derleyici tanımlanmamış davranış asla zamanında idam olacağını varsayabiliriz? Bu mantık için zamanda geri izin vermez.

int num = ReadNumberFromConsole();

if (num == 3) {
 PrintToConsole(num);
 *((char*)NULL) = 0; //undefined behavior
}

Burada derleyici num == 3 her zaman tanımsız davranış çağırmak olacaktır neden olabilir. Bu nedenle, bu durumda imkansız olmalı ve numarası basılı olması gerekmez. if ifadesinin optimize edilmiş olabilir. Ters mantık bu tür standardına göre izin verilir?

CEVAP
18 NİSAN 2014, Cuma


Belirli bir program içinde böyle bir ifadenin varlığı anlamına mı geliyor tüm program tanımlı değil ya da bu davranış, yalnızca tanımsız olur kontrol akış vurur bu deyimi bir kez?

İkisi de değil. İlk şart, çok güçlü ve çok zayıf.

Nesne erişim bazen sıralı, ama standart saati dışında program davranışını açıklar. Danvil zaten dedi:

eğer böyle bir yürütme tanımsız bir işlem, bu içeriyorsa Uluslararası Standart uygulanmasına ilişkin hiçbir gereklilik yerler giriş (bile ile ilgili olan bu programı yürütme işlemleri ilk tanımlanmamış ameliyattan önceki)

Bu yorumlanabilir:

Eğer bu programın çalışmasını tanımsız davranış verir, o zaman bütün program var tanımsız davranış.

Bu yüzden, İK ile ulaşılamaz bir deyimi programı İK vermez. Bu ulaşılabilir bir açıklama (girdi değerleri yüzünden) asla ulaşılır, program İK vermez. Bunun ilk koşulu da güçlü olmasının nedeni bu.

Şimdi, derleyici genel olarak İK ne söyleyemem. Bu yüzden izin iyileştirici Yeniden Sipariş ifadeleri ile potansiyel İK olurdu re-hiç gerekir onların davranış olarak tanımlanan, gerekli izin İK "reach back in time" ve gidip yanlış önce önceki sırası noktası (veya C 11 terminoloji, İK etkileyen şeyler vardır sıralı önce İK şey). Bu nedenle ikinci durumunuz çok zayıf.

Bu önemli bir örnek iyileştirici strict aliasing kullanır. Katı kuralları yumuşatma amacı düzeni yeniden o olamazdı işlemleri geçerli eğer söz konusu işaretçiler aynı bellek takma eğer mümkün olsaydı, Yeniden Sipariş edilmesi derleyici izin vermektir. Yasadışı aliasing işaretçileri kullanın ve İK etmiyorsa, o zaman kolayca "" İK deyim. daha önce bir açıklama etkileyebilir yani Soyut makine ile ilgili olarak İK deyimi henüz idam edilmemiştir. Gerçek nesne kodu ile ilgili olarak, kısmen veya tamamen infaz edilmiştir. Ama standart Yeniden Sipariş tablolara doktoru için ne anlama geldiğini, ya da bunun iması bile İK için ne hakkında detaya almaya çalışmaz. Sadece uygulama lisans yanlış istediği gibi en kısa sürede gitmek verir.

Bu gibi düşünebilirsiniz, "İK bir zaman makinesi var."

Özellikle örnek cevap:

  • Davranış 3 salt okunur, tanımsızdır.
  • Derleyiciler ve eğer temel bir blok bir işlem tanımsız olması için belirli içeriyorsa ölü olarak kod ortadan kaldırmak. İzin veriyorlar (sanırım) bir hukukçu bile değil ama tüm dalları kurşun durumlarda İK. Bu örnek PrintToConsole(3) bir şekilde geri dönmek için emin olmak için bilinen değilse bir aday değil. Ne olursa olsun, özel bir durum ya da atmak olabilir.

İkinci benzer bir örnek gcc seçenek bu gibi bir kod (bu spesifik bir örnek kontrol etmedim, genel bir fikir açıklayıcı düşünün) alabilir -fdelete-null-pointer-checks,:

void foo(int *p) {
    if (p) *p = 3;
    std::cout << *p << '\n';
}

ve değiştirin:

*p = 3;
std::cout << "3\n";

Neden? Eğer p null çünkü o kod neyse İK, derleyici null değil varsayıyorum ve buna göre optimize edebilir. Linux çekirdeği aslında boş bir işaretçi kaldırma bir modda çalışır, çünkü bu (https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-1897) takılmayacakdeğilİK olması gerekiyor, çekirdek kullanabilen tanımlı donanım bir istisna sonuçlanması bekleniyor. Optimizasyon etkinleştirildiğinde, gcc ötesinde standart garanti sağlamak için -fno-delete-null-pointer-checks kullanılması gerekir.

P. S. sorusuna pratik cevap "ne zaman tanımsız davranış gelmiyor mu?" 10 dakika gün için terk etmeyi planlıyordun önce "" dir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Learn Math Tutorials

    Learn Math T

    20 Kasım 2011
  • Matus Slovak

    Matus Slovak

    5 Temmuz 2007
  • PhoneBuff

    PhoneBuff

    10 HAZİRAN 2011