int x; // no initializer. x value is indeterminate.
__std_string__ s; // no initializer, s is default-constructed.
int y = int();
// y is initialized using copy-initialization
// but the temporary uses an empty set of parentheses as the initializer,
// so it is default-constructed.
// A default constructed POD type is zero-initialized,
// therefore, y == 0.
void foo ( __std_string__ ) ;
foo ( __std_string__() ) ;
// the temporary string is default constructed
// as indicated by the initializer ()
```
[#sec:valueinit]
[h5 value-initialization]
The first [@http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html Technical
Corrigendum for the C++ Standard] (TC1), whose draft was released to the public in
November 2001, introduced [@http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#178 Core
Issue 178], among many other issues.
That issue introduced the new concept of `value-initialization`, and also fixed the
wording for zero-initialization. Informally, value-initialization is similar to
default-initialization with the exception that in some cases non-static data members
and base class sub-objects are also value-initialized.
The difference is that an object that is value-initialized will not have, or at least
is less likely to have, indeterminate values for data members and base class sub-objects;
unlike the case of an object default constructed (see Core Issue 178 for a
normative description).
In order to specify value-initialization of an object we need to use the
empty-set initializer: `()`.
As before, a declaration with no initializer specifies default-initialization,
and a declaration with a non-empty initializer specifies copy (`=xxx`) or
direct (`xxx`) initialization.
```
template<class T> void eat(T);
int x ; // indeterminate initial value.
__std_string__ s; // default-initialized.
eat ( int() ) ; // value-initialized
eat ( __std_string__() ) ; // value-initialized
```
[#sec:valueinitsyn]
[h5 value-initialization syntax]
Value initialization is specified using `()`. However, the empty set of
parentheses is not permitted by the syntax of initializers because it is
parsed as the declaration of a function taking no arguments:
```
int x() ; // declares function int(*)()
```
Thus, the empty `()` must be put in some other initialization context.
One alternative is to use copy-initialization syntax:
```
int x = int();
```
This works perfectly fine for POD types. But for non-POD class types,
copy-initialization searches for a suitable constructor, which could be,
for instance, the copy-constructor. It also searches for a suitable conversion
sequence but this does not apply in this context.
For an arbitrary unknown type, using this syntax may not have the
value-initialization effect intended because we don't know if a copy
from a default constructed object is exactly the same as a default
constructed object, and the compiler is allowed, in
some cases, but never required to, optimize the copy away.
One possible generic solution is to use value-initialization of a non static
data member:
```
template<class T>
struct W
{
// value-initialization of 'data' here.
W() : data() {}
T data;
};
W<int> w;
// w.data is value-initialized for any type.
```
This is the solution as it was supplied by earlier versions of the
`__value_initialized__<T>` template class. Unfortunately this approach
suffered from various compiler issues.
[#sec:compiler_issues]
[h5 Compiler issues]
Various compilers have not yet fully implemented value-initialization.
So when an object should be ['value-initialized] according to the C++ Standard,
it ['may] in practice still be left uninitialized, because of those
compiler issues. It is hard to make a general statement on what those issues
are like, because they depend on the compiler you are using, its version number,
and the type of object you would like to have value-initialized.
All compilers we have tested so far support value-initialization for arithmetic types properly.
However, various compilers may leave some types of ['aggregates] uninitialized, when they
should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
go wrong on various compilers.
At the moment of writing, May 2010, the following reported issues regarding
value-initialization are still there in current compiler releases:
* [@https://connect.microsoft.com/VisualStudio/feedback/details/100744 Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression]: Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005.
* [@http://connect.microsoft.com/VisualStudio/feedback/details/484295 Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor] Reported by Sylvester Hesp, 2009.
* [@https://connect.microsoft.com/VisualStudio/feedback/details/499606 Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization] Reported by Alex Vakulenko, 2009
* [@http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized] Reported by Niels Dekker (LKEB), 2010.
* [@http://qc.embarcadero.com/wc/qcmain.aspx?d=84279 Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"] Reported by Niels Dekker, 2010
* Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate. Reported to Steve Clamage by Niels Dekker, 2010.
* IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate. Reported to Michael Wong by Niels Dekker, 2010.
* Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error on Intel 11.1. Reported by John Maddock, 2010.
Note that all known GCC issues regarding value-initialization are fixed with GCC version 4.4, including
[@http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 GCC Bug 30111]. Clang also has completely implemented
value-initialization, as far as we know, now that [@http://llvm.org/bugs/show_bug.cgi?id=7139 Clang Bug 7139]
is fixed.
New versions of __value_initialized__ (Boost release version 1.35 or higher) offer a workaround to these
issues: __value_initialized__ may now clear its internal data, prior to constructing the object that it
contains. It will do so for those compilers that need to have such a workaround, based on the