16

La sección §3.9.1/6 del estándar de C++ dice,la diversión con variables sin inicializar y compilador (GCC)

Los valores de tipo bool son o true o false.

Consideremos ahora este código,

void f(bool b) 
{ 
    switch(b) //since b is bool, it's value can be either true or false! 
    { 
     case true: cout << "possible value - true"; break; 
     case false: cout << "possible value - false"; break; 
     default: cout << "impossible value"; 
    } 
} 
int main() 
{ 
    bool b; //note : b is uninitialized 
    f(b); 
    return 0; 
} 

Compilar F:\workplace>g++ test.cpp -pedantic

Ejecutar. Salida:

valor imposible

salida inesperada? Bueno, no realmente, como se lee el estándar en la nota al pie de §3.9.1/6 que:

Usando un valor bool de manera descrita por esta norma internacional como “indefinido”, como al examinar el valor de un objeto automático no inicializado automático, puede provocar que se comporte como si fuera verdadero o falso.

Así que no importa cuántas veces compilo y ejecute este programa, obtengo el mismo resultado: impossible value. Sin embargo, si cambio un poco - la supresión de la función f() de la imagen, y escribir el bloque switch en main() sí:

int main() 
{ 
    bool b; //note : b is uninitialized 
    switch(b) //since b is bool, it's value can be either true or false! 
    { 
     case true: cout << "possible value - true"; break; 
     case false: cout << "possible value - false"; break; 
     default: cout << "impossible value"; 
    } 
    return 0; 
} 

Entonces compilar y ejecutar este programa, no consigo impossible value como salida; no importa cuántas veces lo repita, nunca recibo impossible value.

Tengo curiosidad por saber por qué este cambio repentino en el comportamiento del bool no inicializado?

Bueno, desde la perspectiva del lenguaje está claro: el comportamiento no está definido. Entiendo eso. También entiendo que el compilador es libre de hacer cualquier cosa. Desde la perspectiva del compilador, sin embargo, esto me parece muy interesante. ¿Qué podría hacer el compilador (es decir, GCC) en cada caso y por qué?

Estoy usando: g++ (GCC) 4.5.0 - MinGW, on Windows 7 Basic, 64-bit OS.

+1

No puedo replicar los resultados con g ++ - 4.4.5 amd64. Pero si quiere contestar a este tipo de preguntas, ¿por qué no examina el resultado de la compilación? – BatchyX

+1

¿Obtiene los mismos resultados si activa la optimización de código? – James

+1

¿Entonces su pregunta es por qué "Comportamiento indefinido" es diferente cuando se expone en diferentes situaciones? ¡Para alguien que sabe que no está definido, no puedo pensar en preguntas más ridículas! y solo puede verlo como una pregunta diseñada para tratar de generar puntos. -500 –

Respuesta

17

Tengo curiosidad por saber por qué este cambio repentino en el comportamiento del bool no inicializado?

Desensamble el código y vea lo que hace el compilador.

Mi suposición: dado que el valor ahora solo se usa localmente, el compilador lo optimiza completamente. Como el comportamiento no está definido de todos modos, el compilador puede asumir cualquier valor de forma segura, p. false.Esta es una optimización bastante obvia ya que el valor de b es constante en lo que respecta al compilador, y toda la lógica del switch es redundante. Entonces, ¿por qué ponerlo en el ejecutable?

(El punto importante aquí es que b solo se usa localmente en el segundo código, y que a su vez activará más optimizaciones incluso en código no optimizado. El primer código debe estar insertado antes de que el compilador pueda hacerlo optimizaciones, o las rutas de los códigos tienen que ser rastreados, que no es trivial).

Cuestiones relacionadas