Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are entries of this STL map not being initialized in GCC 4.5.1?

Here is the code excerpt.

std::map<double, double> temp;

temp[0] = .1;

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

I'm compiling using the GCC version 4.4.1 and I get a value of 0 from temp[1], as I expect. My co-worker is compiling on GCC version 4.5.1. In debug mode (with the -g flag), he gets 1000. When compiling release mode (-O2 flag), he gets 0.

My thought is that this is the type of issue that typically arises with uninitialized variables, except that maps are supposed to call the default constructor on their elements, based on this question and several others like it.

Moreover, The C++ Standard Library by Josuttis, states that

If you use a key as the index, for which no element yet exists, a new element gets inserted into the map automatically. The value of the new element is initialized by the default constructor of its type.

Why are elements in the map not being initialized in GCC 4.5.1 in debug mode? Am I not understanding what others have said about this behavior correctly? Is the default construction of new elements something that is not necessarily part of the standard? Or could this be an actual bug in the compiler?

like image 390
Chance Avatar asked Dec 28 '11 15:12

Chance


3 Answers

It should work the way you say (print 0), and in fact in g++ 4.5.2 it prints 0 with -g, -O2 or both. If it's not printing 0 then that's almost certainly a library bug (or your co-worker's program already has undefined behavior in which case all bets are off (TM)).

like image 187
Mark B Avatar answered Oct 07 '22 09:10

Mark B


Yes it is guaranteed to be initialized to 0 as per the C++ Standard.

Reference:

C++03 Standard:

23.3.1.2 map element access [lib.map.access]

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

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

T() default-initializes an object. While The default values for variables is covered under:

C++03 Standard 8.5/5:

To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
otherwise, the object is zero-initialized.

The last case applies to your code here.

like image 45
Alok Save Avatar answered Oct 07 '22 09:10

Alok Save


As one would expect, the code excerpt is a simplified version of what's really going on. It turns out that a find command is used on the map, so that essentially map.find(1)->second is being called, instead of simply map[1]. This explains the undefined behavior.

like image 29
Chance Avatar answered Oct 07 '22 10:10

Chance