SORU
10 EYLÜL 2015, PERŞEMBE


C derleme hata?

Aşağıdaki kodu var:

#include <iostream>
#include <complex>
using namespace std;

int main() {
    complex<int> delta;
    complex<int> mc[4] = {0};

    for(int di = 0; di < 4; di  , delta = mc[di]) {
        cout << di << endl;
    }

    return 0;
}

Bekliyorum bunun için çıkış "0, 1, 2, 3" ve durdurmak, ama çıkışları bir sonsuz seri "0, 1, 2, 3, 4, 5, ....."

di<4 iyi çalışmaz karşılaştırma gibi görünüyor ve her zaman true değerini döndürür.

Ben sadece ,delta=mc[di], "0, 1, 2, 3" normal. açýklama Masum atama ile sorun nedir?

-O2 seçeneği ile Ideone.com g C 14 kullanıyorum.

CEVAP
10 EYLÜL 2015, PERŞEMBE


Bu muhtemelen tanımsız davranış nedeniyle, mc döngü son yineleme dizi sınırlarının dışında erişiyorsunuz. Bazı Derleyiciler tanımsız davranış varsayımları etrafında agresif döngü optimizasyonu yapabilir. Mantık aşağıdaki gibi olacaktır:

  • Yasak mc erişim tanımsız davranıştır
  • Hayır tanımsız davranış varsayalım
  • Bu nedenle di < 4 aksi mc[di] tanımsız davranış çağır beri her zaman doğrudur

optimizasyon ile gcc açık ve -fno-aggressive-loop-optimizations bayrağı kullanarak sonsuz döngü davranışı kaybolmasına neden olur(see it live). Bir süre* *20 sergiler gözlemlemek sonsuz döngü davranış.

godbolt live example of the code di < 4 kontrol kaldırıldı ve koşulsuz jmp ile: yerini gösterir

jmp .L6

Bu durumda GCC pre-4.8 Breaks Broken SPEC 2006 Benchmarks anlatılan hemen hemen aynıdır. Bu makale için yorum mükemmel ve okumaya değer. Çınlama makale, bu dava için yeniden ama -fsanitize=undefined mu kullanarak gcc yapamam ki -fsanitize=undefined kullanarak olayı yakalayan bu notlarsee it live).

Bu saldırgan bir optimizasyon olsa da, önemli bir C standardı dediği gibi tanımsız davranış olduğunu unutmayın

bu davranış, Uluslararası Standardı gereksinimlerini etkiler

Aslında her şey mümkün ve notları gösterirvurgu benim):

[...]İzin tanımsız davranış durumu görmezden aralıkları tamamenöngörülemeyen sonuçlarçeviri sırasında veya davranışlar için belgelenmiş bir şekilde ortamı (çıkarılması olmadan veya karakteristik olarak program yürütme bir tanılama iletisi), sonlandırmak için bir çeviri veya yürütme (tanı bir mesaj verilmesi ile).[...]

Döngünün dışında cout hareket etmeliyiz ve sonra da aşağıdaki uyarı görüyoruz gcc gelen bir uyarı almak içinsee it live):

warning: iteration 3u invokes undefined behavior [-Waggressive-loop-optimizations]
     for(di=0; di<4;di  ,delta=mc[di]){ }
     ^

muhtemelen ne olup bittiğini anlamaya yetecek kadar bilgi ile OP sağlamak için yeterli olurdu. Böyle tutarsızlık tanımsız davranış ile görebiliriz davranış türleri için tipiktir. Bu waring tanımsız davranış karşısında inconsitent olabilir neden daha iyi bir anlayış Why can't you warn when optimizing based on undefined behavior? almak için iyi bir okuma.

Not -fno-aggressive-loop-optimizations gcc 4.8 release notes belgelenmiştir.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • calicoJake

    calicoJake

    29 EKİM 2007
  • Joseph Herscher

    Joseph Hersc

    14 Mart 2007
  • skiesofblack.net

    skiesofblack

    14 HAZİRAN 2009