34

Recently, I was confused by the std::map operator[] function. In the MSDN library, it says: "If the argument key value is not found, then it is inserted along with the default value of the data type." I tryed to search much more exactly explanation for this issue. For example here: std::map default value In this page, Michael Anderson said that "the default value is constructed by the default constructor(zero parameter constructor)".

Now my quest comes to this:"what the default value for the build-in type?". Was it compiler related? Or is there a standard for this issue by the c++ stardard committee?

I did a test on visual studio 2008 for the "int" type, and found the "int" type is construted with the value 0.

Community
  • 1
  • 1
WKPlus
  • 6,955
  • 2
  • 35
  • 53
  • I did a test with "bool" type. And there is something freaky: when i use "bool b = new bool()", the value of b turns out to be 0; but when i use "bool *pb = new bool[10]; pb[0] = new bool();" and then the pb[0] turns out to be 1, the oppositive value. Oh, I did this test on visual studio 2008. – WKPlus Dec 24 '10 at 04:56
  • 2
    When you wrote `pb[0] = new bool();`, `new bool()` is a *pointer*, whereas `p[0]` is a bool. A pointer can be implicitly converted to `bool`, and gives the result `false` if the pointer is a null pointer, `true` otherwise. So the true value you observed just tells you that `new` didn't return a null pointer (which of course plain `new` never does anyway). Also, you leaked the allocation. – Steve Jessop Feb 28 '12 at 12:15

4 Answers4

31

This is defined in the standard, yes. map is performing "default initialization" in this case. As you say, for class types, that calls a no-arguments constructor.

For built-in types, in the '98 standard, see section 8.5, "Initializers":

To default-initialize an object of type T means:

  • if T is a non-POD ...
  • if T is an array type ...
  • otherwise, the storage for the object is zero-initialized

And, previously,

To zero-initialize storage for an object of type T means:

  • if T is a scalar type, the storage is set to the value 0 (zero) converted to T

Scalar types are:

  • Arithmetic types (integer, floating point)
  • Enumeration types
  • Pointer types
  • Pointer to member types

In particular, the behaviour you see with an integer (initialized to zero) is defined by the standard, and you can rely on it.

Community
  • 1
  • 1
Luke Halliwell
  • 7,312
  • 6
  • 31
  • 31
  • 4
    I just checked this in the C++11 standard, and it says something different. It says that if the type isn't a class or an array, then _no initialization is performed_. So I'm unsure about the default values in the standard containers now. – karadoc Oct 18 '12 at 23:33
  • The quotes from the obsolete standard are misleading because a lot of POD instances do not get default-initialized, by default. The default, even in C++98, for POD types is to not initialize them at all. The terminology was cleaned up (and made horrendously complex) with C++11. Only value-initialization reliably zero-initializes. – Johannes Overmann Jan 18 '22 at 16:23
23

The C++11 standard still requires that std::map zero-initializes built in types (as did the previous standard), but the reasons are a bit different to those in Luke Halliwell's answer. In particular, to 'default-initialize' a built-in data type doesn't mean zero-initialize in the C++11 standard, but rather it would mean 'do nothing'. What actually happens in std::map::operator[] is a 'value-initialization'.

Nevertheless, the end result in the new standard is the same as in Luke's answer. The values will be zero-initialized. Here are the relevant parts of the standard:

Section 23.4.4.3 "map element access" says

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

Effects: If there is no key equivalent to x in the map, inserts value_type(x, T()) into the map.

...

The expression T() is described in section 8.5

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

X a();

And this kind of 'value-initialization' is described in the same section

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized.
karadoc
  • 2,641
  • 22
  • 21
7

The default value of class-type objects is that set by the default constructor of the class. For built-in types the default value is 0.

But note that there is a difference between a built-in variable that isn't initialized, and one initialized to its default value. A built-in that is not initialized will probably hold whatever value was in that variable's memory address at the time.

int i;          // i has an arbitrary undefined value
int x = int();  // x is 0
wilhelmtell
  • 57,473
  • 20
  • 96
  • 131
5
 |expression:   | POD type T                               | non-POD type T
 ==================================================================================================
 | new T         | not initialized                          | default-initialized
 | new T()       | always default-initialized               | always default-initialized
 | new T(x)      | always initialized via a constructor     | always initialized via a constructor

As far as i know, stl uses new T() for default values, so it will be default-initialized, in case of int to 0.

j_kubik
  • 6,062
  • 1
  • 23
  • 42
  • `new T() ` implies value initialization. Value Initialization is different from Default Initialization. – Prasoon Saurav Dec 24 '10 at 03:43
  • new T() implies value initialization? What's the difference between value initialization and default initialization when I use new T()? – WKPlus Dec 24 '10 at 04:23