`int` is a built-in type, which is an example of a Plain Old Data type
like in C, which has no specified default initialization. So, assuming
your array is a local variable, with default initialization nothing happens.
• C++11 §8.5/11:
If no initializer is specified for an object, the object is default-
initialized; ; if no initialization is performed, an object with
automatic or dynamic storage duration has indeterminate value.
• C++11 §8.5/6:
To default-initialize an object of type T means:
— if T is a (possibly cv-qualified) 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, no initialization is performed.
So, by the second dash of §8.5/6, each element of the `int` array is
default-initialized, and by the third dash, since `int` is neither class
type nor an array, no initialization is performed. And then by §8.5/11
again (now applied to array item) that leaves each item with an
indeterminate value.
`std::string` is a class type with a default constructor. Default
initialization for an object of this type uses the default constructor,
which gives you an empty string. This is the first dash of §8.5/6.
× × ×
Things are different if the array is at namespace scope, because
namespace scope variables are zero-initialized before anything else.
× × ×
For a local variable you can get zero initialization by specifying value
initialization, which reduces to call to default constructor or zero
initialization depending on the type. E.g. like this:
int ai[4] = {}; // Very zero'ish.
Alternatively you can use a `std::vector` instead of a raw array:
vector<int> vi( 4 ); // Also very zero'ish.
This relies on the `std::vector` constructor to zero things. In
contrast, for historical reasons (as `boost::array` for C++03) the
`std::array` class has no defined constructor, and doesn't zero things
unless you give an initializer. And so
array<int, 4> argh; // Very indeterminate.
… just gives indeterminate values. :(
One might argue that this proves that the Boost route into
standardization is problematic. While something is proven as part of
Boost, the language evolves (with C++11 supporting list-initialization),
changing the context, so that the Boost thing is now much less than an
optimal solution. It's a proven design, but only for the previous
incarnation of the language; the world is imprefect!
Cheers & hth.,
- Alf