C++14 specifies initialization of objects created with new
in [expr.new]/17 ([expr.new]/15 in C++11, and the note wasn’t a note but normative text back then):
A new-expression that creates an object of type
T
initializes that
object as follows:
- If the new-initializer is omitted, the object is default-initialized (8.5). [ Note: If no initialization is
performed, the object has an indeterminate value. — end note ]- Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.
Default-initialization is defined in [dcl.init]/7 (/6 in C++11, and the wording itself has the same effect):
To default-initialize an object of type
T
means:
- if
T
is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) forT
is called (and the initialization
is ill-formed ifT
has no default constructor or overload resolution
(13.3) results in an ambiguity or in a function that is deleted or
inaccessible from the context of the initialization);- if
T
is an array type, each element is default-initialized;- otherwise, no initialization is performed.
Thus
new A
solely causesA
s default constructor to be called, which does not initializem
. Indeterminate value. Should be the same fornew B
.-
new A()
is interpreted according to [dcl.init]/11 (/10 in C++11):An object whose initializer is an empty set of parentheses, i.e.,
()
, shall be value-initialized.And now consider [dcl.init]/8 (/7 in C++11†):
To value-initialize an object of type
T
means:- if
T
is a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) or a default constructor that is
user-provided or deleted, then the object is default-initialized; - if
T
is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is
zero-initialized and the semantic constraints for
default-initialization are checked, and if T has a non-trivial default
constructor, the object is default-initialized; - if
T
is an array type, then each element is value-initialized; - otherwise, the object is zero-initialized.
Hence
new A()
will zero-initializem
. And this should be equivalent forA
andB
. - if
-
new C
andnew C()
will default-initialize the object again, since the first bullet point from the last quote applies (C has a user-provided default constructor!). But, clearly, nowm
is initialized in the constructor in both cases.
† Well, this paragraph has slightly different wording in C++11, which does not alter the result:
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 forT
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, ifT
’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.