By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,079 Members | 843 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,079 IT Pros & Developers. It's quick & easy.

new X vs new X()

P: n/a
Hi !

Is there any difference between new X and new X() ?!

Regards,
Razvan
Jul 22 '05 #1
Share this Question
Share on Google+
20 Replies


P: n/a
Razvan wrote:
Is there any difference between new X and new X() ?!


There used to be, but only if X is a POD. The first form would
leave it uninitialised, the second would default-initialise it.

Nowadays I am not sure.

V
Jul 22 '05 #2

P: n/a
"Razvan" <mi*****@mailcity.com> wrote in message
news:15*************************@posting.google.co m...
Is there any difference between new X and new X() ?!


Yes, but it is very rare that you should care.

If you say "new X", the initial value of the object allocated is the same as
an uninitialized local variable of the same type would have. So, for
example, the result of "new int" is the address of an uninitialized int, and
the result of "new std::string" is the address of a std::string object with
no characters (because all strings are initialized, if only by the default
constructor). In contrast, the result of "new int()" is the address of an
int with value 0, and the result of "new std::string()" is exactly the same
as the result of "new std::string" (because all strings are initialized, if
only by the default constructor).

This is a relatively recent feature, so if you write a program that relies
on it, you may wish to make sure that your compiler implements it correctly.
Jul 22 '05 #3

P: n/a
Victor Bazarov wrote in news:jB******************@dfw-read.news.verio.net
in comp.lang.c++:
Razvan wrote:
Is there any difference between new X and new X() ?!


There used to be, but only if X is a POD. The first form would
leave it uninitialised, the second would default-initialise it.

Nowadays I am not sure.

Nowadays its value-initialized, which is a kind-of recursive
default-intialization.

In 8.5/5

To value-initialize an object of type T means:

if T is a class type (clause 9) with a user-declared
constructor (12.1), then the default constructor for T
is called (and the initialization is ill-formed if T
has no accessible default constructor);

if T is a non-union class type without a user-declared
constructor, then every non-static data member and
base-class component of T is value-initialized;

8.5/7

An object whose initializer is an empty set of parentheses,
i.e., (), shall be value-initialized.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #4

P: n/a
Rob Williscroft wrote:
Victor Bazarov wrote in news:jB******************@dfw-read.news.verio.net
in comp.lang.c++:

Razvan wrote:
Is there any difference between new X and new X() ?!


There used to be, but only if X is a POD. The first form would
leave it uninitialised, the second would default-initialise it.

Nowadays I am not sure.


Nowadays its value-initialized, which is a kind-of recursive
default-intialization.

In 8.5/5

To value-initialize an object of type T means:

if T is a class type (clause 9) with a user-declared
constructor (12.1), then the default constructor for T
is called (and the initialization is ill-formed if T
has no accessible default constructor);

if T is a non-union class type without a user-declared
constructor, then every non-static data member and
base-class component of T is value-initialized;

8.5/7

An object whose initializer is an empty set of parentheses,
i.e., (), shall be value-initialized.


Thanks, Rob. So, in the case of 'new X', if X is a POD it is still
_uninitialised_. The only difference now is that it's not "default-
initialised" for PODs but "value-initialised", right?

You don't have to reply, I'm just repeating here what Andrew Koenig's
reply stated (I hope).

Victor
Jul 22 '05 #5

P: n/a
Victor Bazarov wrote in news:UC******************@dfw-read.news.verio.net
in comp.lang.c++:
Nowadays its value-initialized, which is a kind-of recursive
default-intialization.

In 8.5/5

To value-initialize an object of type T means:

- if T is a class type (clause 9) with a user-declared
constructor (12.1), then the default constructor for T
is called (and the initialization is ill-formed if T
has no accessible default constructor);

- if T is a non-union class type without a user-declared
constructor, then every non-static data member and
base-class component of T is value-initialized;

8.5/7

An object whose initializer is an empty set of parentheses,
i.e., (), shall be value-initialized.


Thanks, Rob. So, in the case of 'new X', if X is a POD it is still
_uninitialised_. The only difference now is that it's not "default-
initialised" for PODs but "value-initialised", right?

You don't have to reply, I'm just repeating here what Andrew Koenig's
reply stated (I hope).


Ok :), but I will add that value-initialization isn't just for POD's,
it applies to any "non-union class type" without used defined
constructors.

#include <iostream>
#include <ostream>
#include <iomanip>
#include <vector>

struct X
{
std::vector< int > vi;
int x;
};

struct Y
{
std::vector< int > vi;
X x;
};

struct Z
{
std::vector< int > vi;
Y y;
};
void messitup()
{
int array[ 1000 ];
for ( int i = 0; i < 1000; ++i )
{
array[ i ] = 0xCCCCCCC;
}
}

bool is_vi()
{
Z z = Z();
return z.y.x.x == 0;
}

bool is_new_vi()
{
Z *z = new Z();
return z->y.x.x == 0;
}
int main()
{
messitup();

std::cout
<< "value-initialization: "
<< std::boolalpha << is_vi()
<< std::endl
;

std::cout
<< "fake-value-initialization: "
<< std::boolalpha << is_new_vi()
<< std::endl
;
}

1 out of 4 of my compilers returned true, true, 1 returned false, true.
I'm a bit dissapointed gcc 3.4 doesn't support this.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #6

P: n/a
Victor Bazarov posted:
Razvan wrote:
Is there any difference between new X and new X() ?!


There used to be, but only if X is a POD. The first form would
leave it uninitialised, the second would default-initialise it.

Nowadays I am not sure.

V


What's a POD?
-JKop
Jul 22 '05 #7

P: n/a
JKop <NU**@NULL.NULL> wrote in news:u_*****************@news.indigo.ie:
What's a POD?


http://www.parashift.com/c++-faq-lit....html#faq-26.7

Jul 22 '05 #8

P: n/a
"Andrew Koenig" <ar*@acm.org> wrote in message news:<WT*******************@bgtnsc05-news.ops.worldnet.att.net>...
"Razvan" <mi*****@mailcity.com> wrote in message
news:15*************************@posting.google.co m...
Is there any difference between new X and new X() ?!
Yes, but it is very rare that you should care.

If you say "new X", the initial value of the object allocated is the same as
an uninitialized local variable of the same type would have. So, for


This is valid only for the above mentioned POD type. For a
class the call new MyClass is the same with the call new MyClass()
(assuming the class has a default constructor). At least this is what
I understood from you and the previoud posters.

I am rewritting your expression: when calling new X (X is a POD
type) a new object X is created that it is not innitialized.

example, the result of "new int" is the address of an uninitialized int, and
the result of "new std::string" is the address of a std::string object with
no characters (because all strings are initialized, if only by the default
constructor). In contrast, the result of "new int()" is the address of an
int with value 0, and the result of "new std::string()" is exactly the same
as the result of "new std::string" (because all strings are initialized, if
only by the default constructor).
I see. For a POD (like an int) the call new int return a
pointer to an int that is not innitialized (it is not guaranteed to be
zero). OTOH new int() guarantees that the pointer points to an int
innitialized with zero.
For a string it does not matter how you create it because it
is a class that has a constructor and the constructor is called
anyway.

Bottom line:

int* pInt = new int; // the pointer points to an unnitialized int
int* pInt2 = new int() // the pointer points to an int that is
guaranteed to be innitialized to 0
MyClass tst = new MyClass;

is identical with:

MyClass tst2 = new MyClass();

This is a relatively recent feature, so if you write a program that relies
on it, you may wish to make sure that your compiler implements it correctly.


I see. Thanks for the advice.


Regards,
Razvan
Jul 22 '05 #9

P: n/a
"Razvan" <mi*****@mailcity.com> wrote in message
news:15**************************@posting.google.c om...
"Andrew Koenig" <ar*@acm.org> wrote in message news:<WT*******************@bgtnsc05-news.ops.worldnet.att.net>...
"Razvan" <mi*****@mailcity.com> wrote in message
news:15*************************@posting.google.co m... If you say "new X", the initial value of the object allocated is the same as an uninitialized local variable of the same type would have. So, for This is valid only for the above mentioned POD type. For a
class the call new MyClass is the same with the call new MyClass()
(assuming the class has a default constructor). At least this is what
I understood from you and the previoud posters.
That is true, but it is also what I said. Please read it again. For
example:

class Foo { Foo(); /* whatever else you like */ };

In this case, the value of the expression "new Foo" is a pointer to an
object of type Foo that has the same value that an otherwise uninitialized
local variable of type Foo has, namely whatever value is obtained by running
the Foo constructor.
So I stand by my original statement.
I am rewritting your expression: when calling new X (X is a POD
type) a new object X is created that it is not innitialized.
This extra qualification is not necessary.
example, the result of "new int" is the address of an uninitialized int, and the result of "new std::string" is the address of a std::string object with no characters (because all strings are initialized, if only by the default constructor). In contrast, the result of "new int()" is the address of an int with value 0, and the result of "new std::string()" is exactly the same as the result of "new std::string" (because all strings are initialized, if only by the default constructor).

I see. For a POD (like an int) the call new int return a
pointer to an int that is not innitialized (it is not guaranteed to be
zero). OTOH new int() guarantees that the pointer points to an int
innitialized with zero.
Correct.
For a string it does not matter how you create it because it
is a class that has a constructor and the constructor is called
anyway.
Also correct.
Bottom line: int* pInt = new int; // the pointer points to an unnitialized int
int* pInt2 = new int() // the pointer points to an int that is
guaranteed to be innitialized to 0
MyClass tst = new MyClass;

is identical with:

MyClass tst2 = new MyClass();


Only if you have explicitly defined a constructor for MyClass.

Here is the interesting case:

struct Foo {
int i;
string s;
};

Now "new Foo" yields a pointer to a Foo object in which member s is empty
and member i is uninitialized, whereas "new Foo()" yields a pointer to a Foo
object in which member s is empty and member i is zero. Note that Foo is
not a POD type. Nevertheless, the behavior of "new Foo" differs from that
of "new Foo()".
Jul 22 '05 #10

P: n/a
Just for fun:

http://www.horstmann.com/cpp/pitfalls.html
Constructor pitfalls
Example:

int main()
{ string a("Hello");
string b();
string c = string("World");
// ...
return 0;
}
Pitfall:

string b();

This expression does not construct an object b of type string. Instead,
it is the prototype for a function b with no arguments and return type
string.

Moral: Remember to omit the ( ) when invoking the default constructor.

The C feature of declaring a function in a local scope is worthless
since it lies about the true scope. Most programmers place all
prototypes in header files. But even a worthless feature that you never
use can haunt you.
That mean you should better use new X

Mathieu

Razvan wrote:
Hi !

Is there any difference between new X and new X() ?!

Regards,
Razvan


Jul 22 '05 #11

P: n/a
"Mathieu Malaterre" <mm******@nycap.rr.com> wrote in message
news:CY********************@twister.nyroc.rr.com.. .
That mean you should better use new X


Why?
Jul 22 '05 #12

P: n/a
Andrew Koenig wrote:
"Mathieu Malaterre" <mm******@nycap.rr.com> wrote in message
news:CY********************@twister.nyroc.rr.com.. .

That mean you should better use new X

Why?


For being consistant , look:

string s1
string s2 = new string

or

string s1();//<- won't work
string *s2 = new string()

....
Mathieu

Jul 22 '05 #13

P: n/a
"Mathieu Malaterre" <mm******@nycap.rr.com> wrote in message
news:z8********************@twister.nyroc.rr.com.. .
Andrew Koenig wrote:
"Mathieu Malaterre" <mm******@nycap.rr.com> wrote in message
news:CY********************@twister.nyroc.rr.com.. .
That mean you should better use new X
Why?
For being consistant , look: string s1
string s2 = new string or string s1();//<- won't work
string *s2 = new string()


So what? Why is such consistency important?

To put it another way: Consider a class T written by someone else. You are
saying that I should never write

T* tp = new T();

In order to make such a claim credible, you have to tell me what you think I
should write instead. The closest alternative I can think of is

T* tp = new T;
*tp = T();

However, in addition to being more verbose and taking more time to run, this
alternative requires that class T have an assignment operator defined, a
requirement that the first alternative does not share.

So if you are telling me that I should not write the first example above
because of a theoretical concern about "consistency" that doesn't actually
apply in this case, what do you recommend that I do instead?
Jul 22 '05 #14

P: n/a
> In this case, the value of the expression "new Foo" is a pointer to an
object of type Foo that has the same value that an otherwise uninitialized
local variable of type Foo has, namely whatever value is obtained by running
the Foo constructor.
So I stand by my original statement.
I do not understand. After running the constructor the object
is innitialized.

Only if you have explicitly defined a constructor for MyClass.


How about the default constructor ?
Perhaps I am missing something here. Let's suppose I have the
class:

class CTest
{
int counter;

CTest(){}
}
The constructor for CTest does not innitialize the variable
counter. If I create an object:

CTest test;

is the attribute counter guaranteed to be 0 ? (I mean the constructor
does nothing about it; what is happening is this case?)


Regards,
Razvan
Jul 22 '05 #15

P: n/a
"Razvan" <mi*****@mailcity.com> wrote in message
news:15**************************@posting.google.c om...
In this case, the value of the expression "new Foo" is a pointer to an
object of type Foo that has the same value that an otherwise uninitialized local variable of type Foo has, namely whatever value is obtained by running the Foo constructor.
So I stand by my original statement.
I do not understand. After running the constructor the object
is innitialized.
Right. In other words, the result of executing "new Foo" is a pointer to an
object that is initialized in exactly the same way as a local variable
without an explicit initializer, in other words:

{
Foo x;
// ...
}

In both cases (i.e. the local variable x, which has no explicit initializer,
and the object created by "new Foo", which also has no explicit
initializer), the object in question is initialized in the same way (i.e. as
specified by the constructor of class Foo).
Only if you have explicitly defined a constructor for MyClass.

How about the default constructor ?
Perhaps I am missing something here. Let's suppose I have the
class:

class CTest
{
int counter;

CTest(){}
}
You have defined a constructor for class CTest.
The constructor for CTest does not innitialize the variable
counter. If I create an object:

CTest test;

is the attribute counter guaranteed to be 0 ? (I mean the constructor
does nothing about it; what is happening is this case?)


No. You wrote a constructor, and that constructor doesn't initialize the
member "counter", so it's not initialized.
(unless the object in question is static, in which case all data members are
zero-initialized before running the constructor--but that's not what we're
talking about here).

The important case is this one:

class STest {
int counter;
string xyzzy;
};

STest test;

Here, you did not define a constructor for STest, but it effectively has one
anyway, by virtue of having a data member with a constructor. Accordingly,
if "test" is a local variable, the value of test.counter will be undefined.
On the other hand, if you write

STest *p = new STest();

then p will point to an STest object with its counter member initialized to
zero.
Jul 22 '05 #16

P: n/a
Andrew Koenig wrote:

The important case is this one:

class STest {
int counter;
string xyzzy;
};

STest test;

Here, you did not define a constructor for STest, but it effectively has one
anyway, by virtue of having a data member with a constructor. Accordingly,
if "test" is a local variable, the value of test.counter will be undefined.
On the other hand, if you write

STest *p = new STest();

then p will point to an STest object with its counter member initialized to
zero.


Sure about that?
As I see it: STest is not a POD (due to string member xyzzy), thus
the zero initialization does not happen.
If STest would look like this

class STest {
int counter;
char* xyzzy;
};

then

STest *p = new STest();

would initialize counter and xyzzy to 0

( I really hate this rule. If it would be dropped from C++ I wouldn't
leave a single tear for it. Same for implicite return 0 in main() :-)
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #17

P: n/a
Karl Heinz Buchegger wrote:
Andrew Koenig wrote:
The important case is this one:

class STest {
int counter;
string xyzzy;
};

STest test;

Here, you did not define a constructor for STest, but it effectively has one
anyway, by virtue of having a data member with a constructor. Accordingly,
if "test" is a local variable, the value of test.counter will be undefined.
On the other hand, if you write

STest *p = new STest();

then p will point to an STest object with its counter member initialized to
zero.

Sure about that?
As I see it: STest is not a POD (due to string member xyzzy), thus
the zero initialization does not happen.
If STest would look like this

class STest {
int counter;
char* xyzzy;
};

then

STest *p = new STest();

would initialize counter and xyzzy to 0

( I really hate this rule. If it would be dropped from C++ I wouldn't
leave a single tear for it. Same for implicite return 0 in main() :-)


Let's analyse... Unless something is different in the new edition (which
I don't have), here we go:

The default-initialisation is happening for the () form of the
new-initialiser (see 5.3.4/15). That means that for an object of
a class type (not POD, as you mentioned), the default constructor is
called (see 8.5/5). The implicitly defined default constructor behaves
like a user-defined default constructor with an _empty_ initialiser list
(see 12.1/7). If a member is not named in the initialser list (see
12.6.2/4) and it is non-POD (as std::string is) it is default-initialised,
and if it's a POD (like int), it's _uninitialised_.

You're correct, at least where the 1998 version of the Standard is used.
Andrew may or may not be mistaken, we better look in the new edition.

Anybody?

Victor
Jul 22 '05 #18

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:AU***************@ord-read.news.verio.net...
Let's analyse... Unless something is different in the new edition (which
I don't have), here we go:


Something is different in the new edition. I know because I wrote the
proposal for the change.
Jul 22 '05 #19

P: n/a
"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:40***************@gascad.at...
On the other hand, if you write

STest *p = new STest();

then p will point to an STest object with its counter member initialized to zero.
Sure about that?


Yes, I'm sure.
As I see it: STest is not a POD (due to string member xyzzy), thus
the zero initialization does not happen.


It's different in the 2003 standard.

See http://www.open-std.org/jtc1/sc22/wg...g_defects.html, issue 178.
Jul 22 '05 #20

P: n/a
Andrew Koenig wrote:

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:40***************@gascad.at...
On the other hand, if you write

STest *p = new STest();

then p will point to an STest object with its counter member initialized to zero.


Sure about that?


Yes, I'm sure.
As I see it: STest is not a POD (due to string member xyzzy), thus
the zero initialization does not happen.


It's different in the 2003 standard.

See http://www.open-std.org/jtc1/sc22/wg...g_defects.html, issue 178.


I see. Item 35 made the intention clear
One exceptional case less.

Thanks for the clearification.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.