2011-05-29 10 views
10

Bu, C++ 'da programlanırken başıma gelen en garip şey.İncelemeye çalışırken kaybolmuş böcek

Bu benim ana dosyasıdır:

#include <iostream> 
#include "lib/utils.h" 

using namespace std; 

int main(int argc, const char *argv[]) { 
    cout << bin2dec(101000010); 
    return 0; 
} 

ve bu/lib utils.cpp geçerli:

#include <iostream> 
#include "utils.h" 

int bin2dec(int bin) { 
    // 101000010 
    int dec; 
    //std::cout << ""; // If you uncomment this, it works. 
    for (int i = 1; bin > 0; i *= 2, bin /= 10) { 
     if (bin % 2 == 1) { 
      dec += i; 
     } 
    } 
    return dec; 
} 

programı herhangi bir uyarı olmadan derler ve çalıştırdığınızda, bu 450 çıkarır. 450, ondalık cinsinden 101000010 değil, 322'dir. İlk garip olan şey, 482 ve 322 arasındaki farkın tam olarak 128 olması. Bu, dönüştürmeyi denediğiniz herhangi bir ikili sayı ile gerçekleşir. Ama gerçekten garip olan şu ki,ve dec değerini for içinde çıkarıp işlevini hata ayıklama girişimi yapmaya çalıştığımda, aniden doğru çalışmaya başladı.

Temel olarak, herhangi bir nedenle, std::cout işlevinden önce bir şey döndürürse, çalışır. Yapmazsanız, sonuca 128 ekler.

ben g ++ 4.6.0 kullanarak ve bunun gibi derleme:

g++ -c -D NDEBUG -O2  -o 10.o 10.cpp 
g++ -c -D NDEBUG -O2  -o lib/utils.o lib/utils.cpp 
g++ -o 10 -Wl,-S 10.o lib/utils.o lib/menu.o 
+0

İyi bir soru sormak için +1 –

+0

Bu son derece yaygındır - tanımlanmamış davranışların dünyasına hoş geldiniz. –

+0

@Doug Belki de bana sorunun ne olduğunu açıklayabilir misin? –

cevap

23

Aralık başlatılamıyor.

int dec = 0; 
+0

Crap, unuttum. Şimdi aptal gibi hissediyorum. Oh iyi. Teşekkürler! –

+2

@Gerado yapmamalısınız: P Hata yaptığınızda, yaptığınız bir hatanın daha "aptal" ı: P Hepimiz oradaydık ve hepimiz oraya tekrar gidiyoruz. – Wipqozn

0

Oldukça basit, senin sorunun yığın veya yığın işlevin tüm işlemler üzerinde olduğundan, muhtemelen sonradır yığın çökertilmesi çığlıklar Yığın. Programın başka yerlerinde bazı kötü tanımlanmamış davranışlara başvurmadan bu tür bir soruna ulaşamazsınız.

Düzenleme: Evet, örneğin dec'u başlatarak başlayabilirsiniz.

3
int dec; 

dec oluşturur ama asla bir başlangıç ​​değeri (gibi 0) elde edilir. Daha sonra buna değerler eklersiniz ve rastgele bir sonuçla sonuçlanırsınız.

3

Sen işlevinde sıfıra dec başlatmak gerekir: başlatılıyor vermeyerek

int dec = 0; 

, bu değişkenin yerde bellekte olan rastgele olursa olsun rezil başlar. Ve cout << numaralı telefona yapılan çağrı, bu alanda ne kadar sert olduğunu ve dolayısıyla değişiklikleri etkileyebilir. Bu arada, kodunuzu denediğimde, 450'u almıyordum. Bunun bir örneği olan 134514688'u alıyordum.

16

Küçük hata, dec değişkenini başlatmıyor olmanızdır.

Daha büyük hata, derleme sırasında -Wall ve -O2 eklemek için kullanılmadığıdır (yazdığınız programlar daha karmaşık hale geleceğinden çok fazla acıya neden olacak bir şey).

-Wall tüm uyarıları etkinleştirir ve -O2 en iyi duruma getirme gerektirir (eniyileştirme, başlatılmamış değişkenlerle ilgili uyarıları yükseltecek kod yolu çözümlemesini içerir).

+2

Beni buna yen. Her zaman -Wall kullanın. Bazen -Wall yeterli değil. -Wall ile derleme ve optimizasyon, başlatılmamış değişkenler gibi şeyler bulacaktır. –

+0

@David Hammen: Doğru ... daha fazla uyarı görmek için optimizasyon talep etmek önemlidir. Cevabımı düzenledim. – 6502

+0

Duvar * tüm uyarıları etkinleştirmez. Oldukça az uyarı var, -Wall yakalamıyor. -Wall -Wold-style-cast -Woverloaded-virtual -Wshadow kullanıyorum. Mix'e +WeffC++ ekledim, bunun yapılması, GNU'nun standart kütüphane uygulamasından çok fazla gürültü oluşturması değildi. –

İlgili konular