Mis preguntas están divididas en tres partesgcc optimización? ¿error? y su implicación practico para proyectar
Pregunta 1
Consideremos el siguiente código,
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
const int v = 50;
int i = 0X7FFFFFFF;
cout<<(i + v)<<endl;
if (i + v < i)
{
cout<<"Number is negative"<<endl;
}
else
{
cout<<"Number is positive"<<endl;
}
return 0;
}
No se utilizan las opciones específicas de optimización del compilador o la bandera de la junta es usado. Es el comando de compilación básico g ++ -o test main.cpp se usa para formar el ejecutable.
El código aparentemente muy simple, tiene un comportamiento extraño en SUSE 64 bit OS, gcc versión 4.1.2. La salida esperada es "Número es negativo", en cambio solo en SUSE 64 bit OS, la salida sería "Número es positivo".
Después de una cierta cantidad de análisis y haciendo un 'disass' del código, considero que el compilador optimiza en el siguiente formato -
- Desde i es igual en ambos lados de la comparación, no se puede cambiar en la misma expresión, elimine 'i' de la ecuación.
- Ahora, la comparación lleva a
if (v < 0)
, donde v es una constante positiva, por lo que durante la compilación misma, la dirección de la función else cout se agrega al registro. No se pueden encontrar instrucciones cmp/jmp.
Veo que el comportamiento es solo en gcc 4.1.2 SUSE 10. Cuando se prueba en AIX 5.1/5.3 y HP IA64, el resultado es el esperado.
¿Es válida la optimización anterior?
O, ¿está utilizando el mecanismo de desbordamiento para int no es un caso de uso válido?
Pregunta 2
Ahora cuando cambio la sentencia condicional if (i + v < i)
-if ((i + v) < i)
incluso entonces, el comportamiento es el mismo, esto al menos yo personalmente no estar de acuerdo, ya que se proporcionan apoyos adicionales, espero que el compilador para crear una variable de tipo incorporada temporal y comparar, anula la optimización.
Pregunta 3
Supongamos que tengo una enorme base de código, un I migran mi versión del compilador, tales bug/optimización puede causar estragos en mi comportamiento del sistema. Por supuesto, desde la perspectiva empresarial, es muy ineficaz probar todas las líneas de código solo por la actualización del compilador.
Creo que para todo propósito práctico, estos tipos de error son muy difíciles de atrapar (durante la actualización) e invariablemente se filtrarán al sitio de producción.
¿Alguien puede sugerir alguna forma posible de garantizar que este tipo de error/optimización no tenga ningún impacto en mi sistema/código base existente?
PS:
- Cuando la const para v se retira del código, a continuación, la optimización no se hace por el compilador.
- Creo que está perfectamente bien utilizar el mecanismo de desbordamiento para determinar si la variable es de un valor MAX - 50 (en mi caso).
actualización (1)
¿Qué me gustaría lograr? variable, yo sería un contador (tipo de syncID). Si hago una operación fuera de línea (operación 50) y luego durante el inicio, me gustaría reiniciar mi contador, para esto estoy verificando el valor límite (para reiniciarlo) en lugar de agregarlo a ciegas.
No estoy seguro de si confío en la implementación del hardware. Sé que 0X7FFFFFFF es el máximo valor positivo. Todo lo que hago es agregar valor a esto, estoy esperando que el valor de retorno sea negativo. No creo que esta lógica tenga algo que ver con la implementación del hardware.
De todos modos, gracias por su aporte.
Update (2)
La mayoría de los estados INPIT que estoy confiando en el comportamiento de nivel inferior en la comprobación de desbordamiento. Tengo una pregunta con respecto a la misma,
- Si ese es el caso, para un int sin firmar ¿cómo valido y restablezco el valor durante el desbordamiento o el desbordamiento? como si v = 10, i = 0X7FFFFFFE, quiero restablecer i = 9. ¿De manera similar para underflow?
No podría hacer eso a menos que compruebe la negatividad del número. Entonces mi afirmación es que int debe devolver un número negativo cuando se agrega un valor a + MAX_INT.
Háganme saber sus comentarios.
No, no está bien, ya que este es un comportamiento indefinido. Su suposición de que un int es una cantidad de 32 bits en complemento de 2 Y que MAX_INT + algo debe ser negativo es simplemente incorrecto. – Ingo
Quizás pueda decirnos qué está tratando de hacer para que podamos encontrarle una forma de hacerlo. –
Buen ejemplo de por qué no puede decir: "Sé que mi procesador se adapta a un desbordamiento firmado, por lo tanto es seguro". –