2010-10-26 47 views
5

comparar dos códigos como sigue:Tener resultado diferente en diferentes versiones de gcc

1 #include <new> 
    2 #include <cstdio> 
    3 class CA 
    4 { 
    5 public: 
    6  int i, j, k; 
    7 }; 
    8 
    9 int main() 
10 { 
11  int aa[4] = { 1, 2, 3, 4 }; 
12  CA *i = new(aa) CA(); 
13  printf("%d %d %d %d\n", aa[0], aa[1], aa[2], aa[3]); 
14  return 0; 
15 } 

    1 #include <new> 
    2 #include <cstdio> 
    3 class CA 
    4 { 
    5 public: 
    6  int i, j, k; 
    7 }; 
    8 
    9 int main() 
10 { 
11  int aa[4] = { 1, 2, 3, 4 }; 
12  CA *i = new(aa) CA; 
13  printf("%d %d %d %d\n", aa[0], aa[1], aa[2], aa[3]); 
14  return 0; 
15 } 

La diferencia en la línea 12. En entorno de gcc4.1.2, estos dos códigos obtendrá el mismo resultado 1 2 3 4 Pero en gcc4.4 y gcc4.5, el primer código obtendrá 0 0 0 4

¿Por qué?

+0

Creo que esta es una pregunta relevante para este (especialmente las cotizaciones estándar): http://stackoverflow.com/questions/3931312/value-initialization-and-non-pod-types – Naveen

Respuesta

2

En primer lugar, las diferentes versiones de GCC tienen diferentes niveles de conformidad estándar.

En este caso, las versiones posteriores son "más correctas": la inicialización del valor debe tener lugar en el primer fragmento (ya que invoca implícitamente el constructor generado por el compilador predeterminado para una clase con variables miembro POD) y esto conducirá a variables miembro de clase CA inicializado a ceros. Ver this very detailed answer por user Michael Burr, así como this answer a a closely related question.

1

Esa es la ubicación nueva. Inicializó un objeto de tipo CA en esa memoria, y los valores predeterminados para i, j y k son ceros, por lo tanto aa [0], aa [1] amd aa [2] se ponen a cero.

0

Me inclino a pensar que ambas son correctas. Ha sobrescrito (parte de) la memoria utilizada por int aa[4], y luego intente acceder a esa matriz. Eso no es correcto: la memoria contiene un objeto CA y debe accederse a través de ese tipo o un tipo compatible. int [4] y class CA no son tipos compatibles.

Esta regla es importante: un optimizador puede almacenar en caché el valor aa[0] en un registro y no volver a cargar el registro cuando coloque un objeto en la misma dirección de memoria.

+0

Esto no es correcto. Él está usando colocación nueva. El único requisito es que el almacenamiento sea mayor o igual que el tamaño del objeto (y que se cumpla). El gcc 4.1 es menos compatible con el estándar que el gcc 4.5, y esta es solo una de muchas cosas que no son compatibles con el estándar. –

+0

Obviamente es una ubicación nueva, y eso está perfectamente permitido. Lo que no se permite es usar la memoria posteriormente como si la colocación nunca ocurriera. – MSalters

Cuestiones relacionadas