2011-05-29 18 views
10

Esto es lo más extraño que me ha pasado al programar en C++.Error que desaparece al intentar estudiarlo

Este es mi archivo principal:

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

using namespace std; 

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

y esto es lib/utils.cpp:

#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; 
} 

El programa compila sin advertencias, y cuando se ejecuta, se da salida a 450. 450 no es 101000010 en decimal, 322 es. Lo primero extraño es que la diferencia entre 482 y 322 es exactamente 128. Esto sucede con cualquier número binario que intente convertir. Pero lo que es REALMENTE raro, es que cuando traté de generar el valor de bin y dec dentro del for en un intento de depurar la función, de repente comenzó a funcionar correctamente.

Básicamente, por alguna razón, si std::cout algo antes de que la función regrese, funciona. Si no lo hace, agrega 128 al resultado.

estoy usando g ++ 4.6.0, y la compilación de la siguiente manera:

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

+1 para una pregunta bien hecha –

+0

Esto es extremadamente común: bienvenido al mundo del comportamiento indefinido. –

+0

@Doug ¿Quizás me puedas explicar cuál es la pregunta? –

Respuesta

23

No está inicializando dec.

int dec = 0; 
+0

Mierda, lo olvidé. Ahora me siento como un idiota. Oh bien. ¡Gracias! –

+2

@Gerado usted no debe: P El más extraño el error, más "tonto" de un error que ha hecho: P todos hemos estado allí, y estamos todos ir allí de nuevo – Wipqozn

0

Bastante simplemente, su problema grita pila o montón rompiendo a mí-, probablemente, apilar, ya que todas las operaciones de la función son el la pila. No llega a este tipo de problema sin invocar un comportamiento desagradable indefinido en otro lugar del programa.

Editar: Oh, sí, podría comenzar inicializando dec, por ejemplo.

3
int dec; 

Crea dec pero nunca le da un valor inicial (como 0). A continuación, le agrega valores y termina con un resultado aleatorio.

3

Es necesario inicializar los dec a cero en su función:

int dec = 0; 

Al no inicializarlo, que comienza en cualquier porquería aleatoria es en la memoria en lugar de la variable. Y la llamada al cout << puede afectar qué crud está en esa área, de ahí los cambios. Por cierto, cuando probé tu código, no obtenía 450. Estaba obteniendo 134514688 que da un ejemplo de esto.

16

El pequeño error es que no está inicializando la variable dec.

El error más grande es que no se usa para agregar -Wall y -O2 al compilar (algo que causará mucho dolor ya que los programas que escriba se volverán más complejos).

-Wall habilita todas las advertencias y -O2 requiere optimización (la optimización incluye análisis de ruta de código que generará advertencias sobre variables no inicializadas).

+2

se me adelantó. Siempre use -Wall. A veces, Wall no es suficiente. Compilar con -Wall y optimización encontrará cosas como variables sin inicializar. –

+0

@David Hammen: Es cierto ... solicitar la optimización es importante para ver más advertencias. Editado mi respuesta. – 6502

+0

Wall * no * habilita todas las advertencias. Hay bastantes advertencias que -Wall no capta. Yo uso -Wall -Wold-style-cast -Woverloaded-virtual -Wshadow. Agregaría -WeffC++ a la mezcla si no fuera por el hecho de que al hacerlo genera mucho ruido de la implementación de la biblioteca estándar de GNU. –

Cuestiones relacionadas