2011-12-28 16 views
7

Aquí está el extracto del código.¿Por qué las entradas de este mapa STL no se inicializan en GCC 4.5.1?

std::map<double, double> temp; 

temp[0] = .1; 

cout << temp[1] << endl; 
// result varies based on compiler 

Estoy compilando utilizando la versión de GCC 4.4.1 y me da un valor de 0 a temp[1], como espero. Mi compañero de trabajo está compilando en GCC versión 4.5.1. En el modo de depuración (con la bandera -g), obtiene 1000. Al compilar el modo de lanzamiento (-O2 bandera), obtiene 0.

Mi idea es que este es el tipo de problema que normalmente surge con variables no inicializadas, excepto que se supone que los mapas llaman al constructor predeterminado en sus elementos, basado en this question y muchos otros similares.

Por otra parte, El C++ biblioteca estándar por Josuttis, establece que

Si se utiliza una clave como el índice, para el que todavía no existe ningún elemento, un nuevo elemento se inserta en el mapa de forma automática. El valor del nuevo elemento es inicializado por el constructor predeterminado de su tipo.

¿Por qué los elementos en el mapa no se están inicializando en GCC 4.5.1 en modo de depuración? ¿No entiendo lo que otros han dicho sobre este comportamiento correctamente? ¿La construcción predeterminada de nuevos elementos es algo que no es necesariamente parte del estándar? ¿O podría ser esto un error real en el compilador?

+2

Tienes razón. Probablemente tenga corrupción de memoria en otro lado. –

+0

¿Puedes escribir un programa simple compilable que replique el problema? Hacer esto normalmente resolverá su problema, si no, entonces podemos probarlo en nuestros sistemas. –

Respuesta

1

Como era de esperar, el extracto del código es una versión simplificada de lo que realmente está sucediendo. Resulta que se utiliza un comando de búsqueda en el mapa, por lo que esencialmente se llama a map.find(1)->second, en lugar de simplemente map[1]. Esto explica el comportamiento indefinido.

4

Debería funcionar como lo dice (imprimir 0), y de hecho en g ++ 4.5.2 imprime 0 con -g, -O2 o ambos. Si no está imprimiendo 0, es casi seguro que se trata de un error de la biblioteca (o el programa de su compañero de trabajo ya tiene un comportamiento indefinido, en cuyo caso todas las apuestas están desactivadas (TM)).

2

Sí, está garantizado su inicialización en 0 según el estándar C++.

Referencia:

C++ 03 estándar:

23.3.1.2 mapa de acceso elemento[lib.map.access]

T& operator[](const key_type& x);

Returns:(*((insert(make_pair(x, T()))).first)).second.

T() inicialización predeterminada de un objeto. Mientras Los valores predeterminados para las variables están cubiertos en:

C++ 03 Estándar 8.5/5:

Para default-inicializar un objeto de tipo T significa:
- si T es a-POD no tipo de clase (cláusula 9), el constructor predeterminado de T se llama (y la inicialización está mal formada si T no tiene un constructor predeterminado accesible);
- si T es un tipo de matriz, cada elemento se inicializa por defecto;
- de lo contrario, el objeto se inicializa en cero.

El último caso se aplica a su código aquí.

+0

'T()' _value-initializes_ un objeto (§8.5/7). – ildjarn

Cuestiones relacionadas