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?
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)).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With