Default construction of arrays of PODs using new

  • Thread starter Bjarke Hammersholt Roune
  • Start date
B

Bjarke Hammersholt Roune

I have what I think is a very simple question that everyone using C++
should know, yet I cannot find anywhere on the internet where it is
answered, including the FAQ, and I have been using C++ for many years,
and I don't know the answer for sure myself. That feels a bit
embarrassing, but I guess it's just too long ago I used arrays instead
of vector<X>. So now I am asking the question here.

Consider this code:

A* a = new A[10];

What I believe is that the 10 A's will be default-constructed if A is
a non-POD type, while the default-constructor will not be called if A
is a POD type, leaving an array of PODs uninitialized. So the A's
would probably need to be initialized separately if they are PODs,
even if A has a suitable default constructor, e.g. if A=int. Is this
true?

Now consider this code, which has () at the end:

A* a = new A[10]();

I've never seen this in actual code, and I can't find an explanation
of it on the internet. What I suspect from the few discussions of it I
have seen is that this will guarantee that the default constructor
will be called, no matter if A is a POD type or not. So e.g. if A=int,
this will initialize the elements of the array to zero. Is this true?

If no default constructor has been explicitly defined for A, then a
compiler-generated default constructor will be used, which will not
initialize any POD members (which will be all the members if A is a
POD), so the array will still be in need of initialization if A is a
POD that is not a built in type and for which no default constructor
has been defined. Is that right?

Thank you so much for any help you can give me on this.

Cheers
Bjarke Hammersholt Roune
 
B

Bjarke Hammersholt Roune

So I guess you are not right, if T is zero-initialized then all its POD
members are zero-initialized also.
Interesting answer to the third question - this introduces another
concept: zero-initialization. If what I wrote for the first two
questions is correct, then no zero-initialization occurs, since what I
wrote was all about the default constructor being called or not. In
that case zero-initialization isn't relevant to the question, since
zero-initialization isn't what happens in the two lines I wrote, even
if the result of calling the default constructors would be the same as
zero-initialization for the case that A=int. However, it is also
possible that I was wrong and what happens when you write

A* a = new A[10];

or perhaps

A* a = new A[10]();

is zero-initialization and not default construction. In that case it
certainly is relevant.

I now know more but am more confused! :)

Cheers
Bjarke Hammersholt Roune
 
A

Alf P. Steinbach

* Kai-Uwe Bux:
James said:
Now consider this code, which has () at the end:
A* a = new A[10]();
I've never seen this in actual code,
That's probably because it's illegal.

Really? compiles fine with Comeau and g++. Also, the syntax in [5.3.4/1]
seems to allow it. However, I have a bit trouble deducing its meaning from
the standard :-(

C++98 §5.3.4/15 "If the new-initializer is of the form (),
default-initialization shall be performed (8.5)"


Cheers & hth.,

- Alf
 
B

Bjarke Hammersholt Roune

From the draft 2 of the standard that I could find online, it says:

To default-initialize an object of type T means:
— if T is a non-POD class type (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 storage for the object is zero-initialized.

That got me looking for what exactly the definition of a POD is

A POD-struct is an aggregate class that has no non-static data
members of type pointer to member, non-
POD-struct, non-POD-union (or array of such types) or reference, and
has no user-defined copy assignment
operator and no user-defined destructor.
An aggregate is an array or a class (9) with no user-declared
constructors (12.1), no private or protected
non-static data members (11), no base classes (10), and no virtual
functions (10.3).

and then what an aggregate class is

An aggregate is an array or a class (9) with no user-declared
constructors (12.1), no private or protected
non-static data members (11), no base classes (10), and no virtual
functions (10.3).
A POD-struct is an aggregate class that has no non-static data
members of type pointer to member, non-
POD-struct, non-POD-union (or array of such types) or reference, and
has no user-defined copy assignment
operator and no user-defined destructor.

I didn't know that PODs cannot have user defined constructors. So
combining that with the other messages in this thread, it seems that
new A[10]() will zero-initialize a POD and default construct a non-POD
A. Also, new A[10] will leave PODs uninitialized, but will default
construct non-PODs:

— If the new-initializer is omitted:
— If T is a (possibly cv-qualified) non-POD class type (or array
thereof), the object is default-
initialized (8.5). If T is a const-qualified type, the underlying
class type shall have a user-declared
default constructor.
— Otherwise, the object created has indeterminate value. If T is a
const-qualified type, or a (possibly
cv-qualified) POD class type (or array thereof) containing (directly
or indirectly) a member of
const-qualified type, the program is ill-formed;

Thanks for the help.

Cheers
Bjarke Hammersholt Roune
 
J

James Kanze

* Kai-Uwe Bux:
James Kanze wrote:
On Apr 14, 4:57 pm, Bjarke Hammersholt Roune <[email protected]>
wrote:
Now consider this code, which has () at the end:
A* a = new A[10]();
I've never seen this in actual code,
That's probably because it's illegal.
Really? compiles fine with Comeau and g++. Also, the syntax
in [5.3.4/1] seems to allow it. However, I have a bit
trouble deducing its meaning from the standard :-(
C++98 §5.3.4/15 "If the new-initializer is of the form (),
default-initialization shall be performed (8.5)"

Which was changed to value-initialization in C++03.

I remembered that you couldn't normally provide an initializer
for an array in new; an empty initializer is a special case
I wasn't aware of.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top