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

M

Mario Fratelli

MyClass *p = new MyClass;
MyClass *p = new MyClass();

do they mean something different?

Thanks a lot,
Mario Fratelli.
 
M

Moonlit

Hi,

Mario Fratelli said:
MyClass *p = new MyClass;
MyClass *p = new MyClass();

do they mean something different?

No, but note that:

MyClass p;
and
MyClass p();

does mean something different. The first is creating an object of MyClass.
The second is prototyping a function p() returning MyClass;


Regards, Ron AF Greve
 
A

Alf P. Steinbach

MyClass *p = new MyClass;
MyClass *p = new MyClass();

do they mean something different?

Yes, they do.

If MyClass is a POD (Plain Old Datastructure), roughly, no virtual
functions and no user-defined constructors, then with a standard-
conforming compiler the first statement creates a new instance without
initializing it, whereas the second gives default-initialization,
which for POD fields is zeroing.

If MyClass is not a POD then the two statements are equivalent.
 
A

Andrew Koenig

MyClass *p = new MyClass;
MyClass *p = new MyClass();

do they mean something different?

Yes: In the first example, p points at an object that is
default-initialized; in the second case, p points at an object that is
value-initialized.

Default- and value-initialization differ only in the case where MyClass does
not have a user-defined constructor (although it might have data members of
classes that themselves have user-defined constructors). For example:

class MyClass {
public:
std::string name, address;
int postalcode;
};

In both examples above, the initial values of p->name and p->address will be
empty strings. However, in the first case, p->postalcode will be undefined,
whereas in the second case (p = new MyClass()), p->postalcode will be zero.

Note that this behavior is a change from C++98; many compilers do not yet
implement this behavior correctly.
 
R

Rob Williscroft

Mario Fratelli wrote in
MyClass *p = new MyClass;
MyClass *p = new MyClass();

do they mean something different?

Yes, but only in the case where MyClass *doesn't* have any constructors,
particularly a default ctor.

If so in the second case, "value initialization" (IIRC) is used,
which means all of MyClass members are initialized by "value
initialization", a recursive thing that ultimatly leads to the members
default constructors being called or in the case of inbuilt types
they are 0 initialized.

Note that for this to work all of MyClass 's members must have *no* user
defined constructors *or* they must also have a user defined default
constructor, this rule applies recusivly too.

example (simple):

class MyClass
{
public:

int i;
};

MyClass *initialized = new MyClass();
MyClass *not_initialized = new MyClass;

intialized->i == 0;
not_intialized->i == /* un-initialized (AKA garbage) */;

not_intialized->i should be initialized before it is value is used or
the programme will exhibit undefined behaviour.

HTH.

Rob.
 
M

Mario Fratelli

Andrew Koenig said:
Note that this behavior is a change from C++98; many compilers do not yet
implement this behavior correctly.

since the behaviour is differente only when you don't have default
constructors, how can I test the compiler?

Mario Fratelli.
 
V

Victor Bazarov

Mario Fratelli said:
"Andrew Koenig" <[email protected]> wrote in message

since the behaviour is differente only when you don't have default
constructors, how can I test the compiler?

It's rather difficult. It would involve using an uninitialised values
of POD, which in itself can cause undefined behaviour.

But try this:

struct A {
int a;
};
#include <iostream>
int main() {
char *storage = new char[sizeof(A)];
for (int i = 0; i < sizeof(A); ++i)
storage = 1;
A *pa = new (storage) A;
std::cout << pa->a << std::endl;
pa = new (storage) A();
std::cout << pa->a << std::endl;
delete[] storage;
}

If you get two zeroes as output, your compiler value-initialises
PODs when it is supposed to leave it uninitialised.

Make sure to build a release version as debug ones often initialise
values to 0 without your specific actions.

Victor

P.S. I tested this with VC++ v6sp5 (and it failed to default-
initialise the 'A' the second time) and with Intel C++ v4.5, which
gave the expected output:

16843009
0

(well, the first value is not something specifically expected, just
so it is not 0)
 
A

Alf P. Steinbach

Yes, they do.

If MyClass is a POD (Plain Old Datastructure), roughly, no virtual
functions and no user-defined constructors, then with a standard-
conforming compiler the first statement creates a new instance without
initializing it, whereas the second gives default-initialization,
which for POD fields is zeroing.

If MyClass is not a POD then the two statements are equivalent.

Among 112 spams and Swen viruses a mail from Andrew Koenig, almost deleted
in my spam-removal frenzy, pointing my attention to that last sentence.

Ooops.

And thanks, Andrew.

While the sentence holds wrt. C++ 1998, the C++ 2003 standard revision changed
the rules slightly. The relevant paragraps are §5.3.4/15, which defines the
effect with and without "()", and §8.5/5, which defines the terms
"zero-initialization", "default-initialization" and, in C++ 2003, the new term
"value-initialization". In C++ 2003, the 'new' statement with "()" gives
value-initialization, which is not necessarily equivalent to
default-initialization: roughly, value-initialization only calls the default
constructor if it is a user-defined constructor, and otherwise gives
zero-initialization. So "()" can no longer be read as "call constructor".

The upshot is that in C++ 2003 you're guaranteed zero-initialization in at
least one more case than in C++ 1998, namely in the case of "new T()" where T
is non-POD and does not have a user-defined constructor.

This language keeps getting subtler and subtler.
 
A

Andrew Koenig

The upshot is that in C++ 2003 you're guaranteed zero-initialization in at
least one more case than in C++ 1998, namely in the case of "new T()" where T
is non-POD and does not have a user-defined constructor.

This language keeps getting subtler and subtler.

Actually, the purpose of this change (of which I was the instigator, which
is why I know about it), is to *remove* a subtlety as seen from the user's
viewpoint. Consider:

struct Person {
NameType name;
long id;
};

What is the value of Person().id? In C++98, it is not possible to answer
that question without examining the definition of NameType. In C++2003, the
answer is always 0.
 
J

jeffc

Andrew Koenig said:
Yes: In the first example, p points at an object that is
default-initialized; in the second case, p points at an object that is
value-initialized.

Presumably, value initialization is preferred?
 
R

Ron Natalie

Andrew Koenig said:
Yes: In the first example, p points at an object that is
default-initialized; in the second case, p points at an object that is
value-initialized.

Default- and value-initialization differ only in the case where MyClass does
not have a user-defined constructor (although it might have data members of
classes that themselves have user-defined constructors). For example:
Despite the changes in the TC1 languatge, the first is still NOT default initialization
for POD's. For POD's NO initialization is done.
 
D

Dave

Andrew Koenig said:
Actually, the purpose of this change (of which I was the instigator, which
is why I know about it), is to *remove* a subtlety as seen from the user's
viewpoint. Consider:

struct Person {
NameType name;
long id;
};

What is the value of Person().id? In C++98, it is not possible to answer
that question without examining the definition of NameType. In C++2003, the
answer is always 0.

In C++98, why is it that the value of Person().id depends on the definition
of NameType? I would have thought that id would be uninitialized in C++98
and would have been zero-initialized in C++2003, regardless of the
definition of NameType, but I am clearly mistaken...

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...

Also, of the more prevelant compilers, which currently implement C++98
semantics and which currently implement C++2003 semantics?
 
E

E. Robert Tisdale

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

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

E. Robert Tisdale

Andrew said:
Yes: In the first example,
p points at an object that is default-initialized;
in the second case,
p points at an object that is value-initialized.

Where did this terminology come from?
(Are you making this up?)
Default- and value-initialization differ only in the case
where MyClass does not have a user-defined constructor
(although it might have data members of classes
that themselves have user-defined constructors). For example:

class MyClass {
public:
std::string name, address;
int postalcode;
};

\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}
In both examples above,
the initial values of p->name and p->address will be empty strings.
However, in the first case,
p->postalcode will be undefined,
whereas in the second case
(p = new MyClass()), p->postalcode will be zero.

Note that this behavior is a change from C++98;
many compilers do not yet implement this behavior correctly.

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

Andrey Tarasevich

Dave said:
In C++98, why is it that the value of Person().id depends on the definition
of NameType?

Because, once again, the value of 'Person().id' depends on whether
'Person' is POD or non-POD. And there's no way to answer this question
until you know what 'NameType' is. If 'NameType' is an alias for
'std::string', then 'Person' is not POD and the value of 'Person().id'
is unspecified. If 'NameType' is an alias for 'int', then 'Person' is
POD and the value of 'Person().id' is 0.
I would have thought that id would be uninitialized in C++98

It's already been said many times here, that in C++98 '()' initializer
causes default-initialization, which means zero-initialization for POS
types. That's why for POD types 'Person().id' is 0 in C++98
and would have been zero-initialized in C++2003, regardless of the
definition of NameType, but I am clearly mistaken...

Yes, it will be zero-initialized in C++2003
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...

If you don't have a copy of the C++98 standard, you can simply download
a copy of draft C++98 standard for free and find all this information
there. The same applies to TC1. Or simply google the net for
value-initialization.
 
A

Andrew Koenig

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

Right you are. Sorry about that.
 
A

Andrew Koenig

In C++98, why is it that the value of Person().id depends on the
definition
of NameType? I would have thought that id would be uninitialized in C++98
and would have been zero-initialized in C++2003, regardless of the
definition of NameType, but I am clearly mistaken...

Suppose I defined NameType this way:

typedef int NameType;

Then my Person type is a POD, which would get zero-initialized in C++98.
 
R

Ron Natalie

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

Correct, it is not DEFAULT INITIALIZATION. Default initialization
is still zero initialization for POD's. TC1 doesn't change that.
The value, as far as the standard is concerned is indeterminate.
If the compiler wants to make it determinate, that's fine, but it's
not something a programmer can rely on.
 

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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top