is there a difference between new MyClass; and new MyClass();?

R

Ron Natalie

Dave said:
Having followed the whole thread, I'm still a bit confused. I wonder if
someone might post a concise but comprehensive summary of behavior under
both C++98 and C++2003 as well as definitions of relevant terms such as
default-initialize, value-initialize, zero-initialize, etc...
Ok, here's the poop on initialization.

This part is the same before and after TC1.

There is a concept called default initialization. Default initialization means for, non-POD types
to run the constructor. For POD types, it means zero initialization. However, the confusing issue
is that POD's are sometimes not default initialized. For example, default initialization is skipped
with allocation via new (without the parens) and also for auto (local non-static) variables. This
I believe is a major defect in the language, but you'll never convince the bean counters that
consistant behavior is worth making people clean up their old code if they really want to create
an uninitialized variable.

What TC1 added is value initialization. Value initialization was added to the new() case and
what it says is that if the non-POD class has no default constructor, then any pod's would be
zero initialized where they wouldn't have been in the default initialization case.

The item it is fixing is this:

struct X {
SomeType st;
PodType pod;
};

new X(); in pre-TC1, if SomeType was not POD, then X would not be POD, and hence pod
would not be initialized (because X's implicitly generated constructor doesn't do it). In post TC1,
the value initialization is applied to st and pod when X is value initialized. st's implicit constructor
runs and pod gets zero'd.
 
R

Ron Natalie

E. Robert Tisdale said:
Where did this terminology come from?
(Are you making this up?)

It was introduced in TC1. It's part of the language now.

What changes this behavior? Some new ANSI/ISO C++ standard?
If so, please cite and quote the relevant passage.

The new 5.3.4 of TC1 changes the behavior of new () from default to value initialization.
The new 8.5 defines value initialization (right after default initialization) to say that if
there is no default constructor (even on POD types), then each base or member is
value initialized in turn (which means zero initialized for pods).
 
A

Andrey Tarasevich

E. Robert Tisdale said:
I believe that it is up to the compiler developer
to decide whether PODs are initialized or not.
...

Of course, it is! The standard says that in this case POD contains
_indeterminate_ _value(s)_, which means that it might contain virtually
anything. The compiler developer might decide to initialize it with
zeros. Or he might decide to put his girlfriend's initials and today's
date into each integral component of POD. That, of course, will be
nothing more than waste of time and code, since the user code will
re-initialize every "non-initialized" POD anyway.
 
D

Dave

Ron Natalie said:
Ok, here's the poop on initialization.

This part is the same before and after TC1.

There is a concept called default initialization. Default initialization means for, non-POD types
to run the constructor. For POD types, it means zero initialization. However, the confusing issue
is that POD's are sometimes not default initialized. For example,
default initialization is skipped
with allocation via new (without the parens) and also for auto (local non-static) variables. This
I believe is a major defect in the language, but you'll never convince the bean counters that
consistant behavior is worth making people clean up their old code if they really want to create
an uninitialized variable.

What TC1 added is value initialization. Value initialization was added to the new() case and
what it says is that if the non-POD class has no default constructor, then any pod's would be
zero initialized where they wouldn't have been in the default initialization case.

The item it is fixing is this:

struct X {
SomeType st;
PodType pod;
};

new X(); in pre-TC1, if SomeType was not POD, then X would not be POD, and hence pod
would not be initialized (because X's implicitly generated constructor doesn't do it). In post TC1,
the value initialization is applied to st and pod when X is value
initialized. st's implicit constructor
runs and pod gets zero'd.

Ahhh, there it is! Thank you! This helps tremendously and is well-written!
 
A

Andrew Koenig

MyClass *p = new MyClass;
Where did this terminology come from?

The C++ standard.
(Are you making this up?)

Yes, but only in the sense that I originated the proposal that resulted in
this terminology becoming part of the standard.
\begin{nit}
Shame on you!
This example would have served its purpose just as well
if you had made the data members private.
\end{nit}

I disagree. If I had made the data members private, p->postalcode (which
appears below) would be an access violation.
What changes this behavior? Some new ANSI/ISO C++ standard?

Yes -- the C++ 2003 standard.
If so, please cite and quote the relevant passage.

http://std.dkuug.dk/JTC1/SC22/WG21/docs/cwg_defects.html

See issues 178 and 35.
 
P

Phlip

Ron said:
Despite the changes in the TC1 languatge, the first is still NOT default initialization
for POD's. For POD's NO initialization is done.

Try this:

int * p = new int();
assert( 0 == *p );
 
E

E. Robert Tisdale

Andrey said:
Of course, it is! The standard says that, in this case,
POD contains _indeterminate_ _value(s)_
which means that it might contain virtually anything.
The compiler developer might decide to initialize it with anything.
Or 'he might decide to put his girlfriend's initials and today's date
into each integral component of POD.
That, of course,
will be nothing more than waste of time and code, since
the user code will re-initialize every "non-initialized" POD anyway.

No. It isn't a waste of time or code.
The compiler developer might provide an option
which initializes undefined variables with values
(INT_MIN, UINT_MAX, a signaling NaN, etc.)
that are likely to result in noticeable run-time errors
if the variables are not initialized explicitly before use.
This option would help programmers detect bugs
so they could fix them before recompiling
with the option turned off.
 
A

Andrey Tarasevich

Phlip said:
Try this:

int * p = new int();
assert( 0 == *p );
...

You are not following the discussion. Ron clearly stated that he is
talking about the _first_ case

MyClass *p = new MyClass;

No initializer is provided. No initialization is performed.

Now, would you please explain, what is is the relevance of your example
(which uses explicit '()' initializer) to this branch of the discussion?
 
R

Ron Natalie

Phlip said:
Try this:

int * p = new int();
assert( 0 == *p );
That's not the case I was talking about. I said the first case (in the original posters
program). IT does not have () after the type name.
 
P

Phlip

Ron said:
That's not the case I was talking about. I said the first case (in the original posters
program). IT does not have () after the type name.

I didn't read that far back, so I wrote ambiguously.

Even this works, but it looks freaky!

assert( 0 == int() );
 

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

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top