new X vs new X() 
July 22nd, 2005, 01:35 PM
| | | new X vs new X()
Hi !
Is there any difference between new X and new X() ?!
Regards,
Razvan | 
July 22nd, 2005, 01:35 PM
| | | Re: new X vs new X()
Razvan wrote:[color=blue]
> Is there any difference between new X and new X() ?![/color]
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 | 
July 22nd, 2005, 01:35 PM
| | | Re: new X vs new X()
"Razvan" <mihai11@mailcity.com> wrote in message
news:15f19d61.0406220529.a1c7496@posting.google.co m...
[color=blue]
> Is there any difference between new X and new X() ?![/color]
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. | 
July 22nd, 2005, 01:35 PM
| | | Re: new X vs new X()
Victor Bazarov wrote in news:jBWBc.1470$ri.119654@dfw-read.news.verio.net
in comp.lang.c++:
[color=blue]
> Razvan wrote:[color=green]
>> Is there any difference between new X and new X() ?![/color]
>
> 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.
>[/color]
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/ | 
July 22nd, 2005, 01:35 PM
| | | Re: new X vs new X()
Rob Williscroft wrote:[color=blue]
> Victor Bazarov wrote in news:jBWBc.1470$ri.119654@dfw-read.news.verio.net
> in comp.lang.c++:
>
>[color=green]
>>Razvan wrote:
>>[color=darkred]
>>>Is there any difference between new X and new X() ?![/color]
>>
>>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.
>>[/color]
>
>
>
> 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.[/color]
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 | 
July 22nd, 2005, 01:36 PM
| | | Re: new X vs new X()
Victor Bazarov wrote in news:UCXBc.1476$ri.119739@dfw-read.news.verio.net
in comp.lang.c++:
[color=blue][color=green]
>> 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.[/color]
>
> 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).
>[/color]
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/ | 
July 22nd, 2005, 02:05 PM
| | | Re: new X vs new X()
Victor Bazarov posted:
[color=blue]
> Razvan wrote:[color=green]
>> Is there any difference between new X and new X() ?![/color]
>
> 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[/color]
What's a POD?
-JKop | 
July 22nd, 2005, 02:06 PM
| | | Re: new X vs new X()
"Andrew Koenig" <ark@acm.org> wrote in message news:<WTWBc.16084$OB3.13332@bgtnsc05-news.ops.worldnet.att.net>...[color=blue]
> "Razvan" <mihai11@mailcity.com> wrote in message
> news:15f19d61.0406220529.a1c7496@posting.google.co m...
>[color=green]
> > Is there any difference between new X and new X() ?![/color]
>
> 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[/color]
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.
[color=blue]
> 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).[/color]
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();
[color=blue]
> 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.[/color]
I see. Thanks for the advice.
Regards,
Razvan | 
July 22nd, 2005, 03:15 PM
| | | Re: new X vs new X()
"Razvan" <mihai11@mailcity.com> wrote in message
news:15f19d61.0406230000.7fc9d928@posting.google.c om...[color=blue]
> "Andrew Koenig" <ark@acm.org> wrote in message[/color]
news:<WTWBc.16084$OB3.13332@bgtnsc05-news.ops.worldnet.att.net>...[color=blue][color=green]
> > "Razvan" <mihai11@mailcity.com> wrote in message
> > news:15f19d61.0406220529.a1c7496@posting.google.co m...[/color][/color]
[color=blue][color=green]
> > If you say "new X", the initial value of the object allocated is the[/color][/color]
same as[color=blue][color=green]
> > an uninitialized local variable of the same type would have. So, for[/color][/color]
[color=blue]
> 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.[/color]
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.
[color=blue]
> 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.[/color]
This extra qualification is not necessary.
[color=blue][color=green]
> > example, the result of "new int" is the address of an uninitialized int,[/color][/color]
and[color=blue][color=green]
> > the result of "new std::string" is the address of a std::string object[/color][/color]
with[color=blue][color=green]
> > no characters (because all strings are initialized, if only by the[/color][/color]
default[color=blue][color=green]
> > constructor). In contrast, the result of "new int()" is the address of[/color][/color]
an[color=blue][color=green]
> > int with value 0, and the result of "new std::string()" is exactly the[/color][/color]
same[color=blue][color=green]
> > as the result of "new std::string" (because all strings are initialized,[/color][/color]
if[color=blue][color=green]
> > only by the default constructor).[/color][/color]
[color=blue]
> 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.[/color]
Correct.
[color=blue]
> 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.[/color]
Also correct.
[color=blue]
> Bottom line:[/color]
[color=blue]
> 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();[/color]
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()". | 
July 22nd, 2005, 03:16 PM
| | | Re: new X vs new X()
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:[color=blue]
> Hi !
>
>
>
> Is there any difference between new X and new X() ?!
>
>
>
> Regards,
> Razvan[/color] | 
July 22nd, 2005, 03:17 PM
| | | Re: new X vs new X()
"Mathieu Malaterre" <mmalater@nycap.rr.com> wrote in message
news:CYjCc.114762$j24.24026@twister.nyroc.rr.com.. .
[color=blue]
> That mean you should better use new X[/color]
Why? | 
July 22nd, 2005, 03:17 PM
| | | Re: new X vs new X()
Andrew Koenig wrote:[color=blue]
> "Mathieu Malaterre" <mmalater@nycap.rr.com> wrote in message
> news:CYjCc.114762$j24.24026@twister.nyroc.rr.com.. .
>
>[color=green]
>>That mean you should better use new X[/color]
>
>
> Why?
>
>[/color]
For being consistant , look:
string s1
string s2 = new string
or
string s1();//<- won't work
string *s2 = new string()
....
Mathieu | 
July 22nd, 2005, 03:17 PM
| | | Re: new X vs new X()
"Mathieu Malaterre" <mmalater@nycap.rr.com> wrote in message
news:z8lCc.114776$j24.33923@twister.nyroc.rr.com.. .[color=blue]
> Andrew Koenig wrote:[color=green]
> > "Mathieu Malaterre" <mmalater@nycap.rr.com> wrote in message
> > news:CYjCc.114762$j24.24026@twister.nyroc.rr.com.. .[/color][/color]
[color=blue][color=green][color=darkred]
> >>That mean you should better use new X[/color][/color][/color]
[color=blue][color=green]
> > Why?[/color][/color]
[color=blue]
> For being consistant , look:[/color]
[color=blue]
> string s1
> string s2 = new string[/color]
[color=blue]
> or[/color]
[color=blue]
> string s1();//<- won't work
> string *s2 = new string()[/color]
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? | 
July 22nd, 2005, 03:18 PM
| | | Re: new X vs new X()
> In this case, the value of the expression "new Foo" is a pointer to an[color=blue]
> 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.[/color]
I do not understand. After running the constructor the object
is innitialized.
[color=blue]
> Only if you have explicitly defined a constructor for MyClass.[/color]
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 | 
July 22nd, 2005, 03:18 PM
| | | Re: new X vs new X()
"Razvan" <mihai11@mailcity.com> wrote in message
news:15f19d61.0406240421.423abe7a@posting.google.c om...
[color=blue][color=green]
> > 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[/color][/color]
uninitialized[color=blue][color=green]
> > local variable of type Foo has, namely whatever value is obtained by[/color][/color]
running[color=blue][color=green]
> > the Foo constructor.
> > So I stand by my original statement.[/color][/color]
[color=blue]
> I do not understand. After running the constructor the object
> is innitialized.[/color]
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).
[color=blue][color=green]
> > Only if you have explicitly defined a constructor for MyClass.[/color][/color]
[color=blue]
> How about the default constructor ?
> Perhaps I am missing something here. Let's suppose I have the
> class:
>
> class CTest
> {
> int counter;
>
> CTest(){}
> }[/color]
You have defined a constructor for class CTest.
[color=blue]
> 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?)[/color]
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. | 
July 22nd, 2005, 03:20 PM
| | | Re: new X vs new X()
Andrew Koenig wrote:[color=blue]
>
> 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.[/color]
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 kbuchegg@gascad.at | 
July 22nd, 2005, 03:20 PM
| | | Re: new X vs new X()
Karl Heinz Buchegger wrote:[color=blue]
> Andrew Koenig wrote:
>[color=green]
>>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.[/color]
>
>
> 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() :-)[/color]
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 | 
July 22nd, 2005, 03:20 PM
| | | Re: new X vs new X()
"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:AUVCc.254$vw1.881@ord-read.news.verio.net...
[color=blue]
> Let's analyse... Unless something is different in the new edition (which
> I don't have), here we go:[/color]
Something is different in the new edition. I know because I wrote the
proposal for the change. | 
July 22nd, 2005, 03:20 PM
| | | Re: new X vs new X()
"Karl Heinz Buchegger" <kbuchegg@gascad.at> wrote in message
news:40DBEAF3.4024FEAE@gascad.at...
[color=blue][color=green]
> > On the other hand, if you write
> >
> > STest *p = new STest();
> >
> > then p will point to an STest object with its counter member initialized[/color][/color]
to[color=blue][color=green]
> > zero.[/color]
>
> Sure about that?[/color]
Yes, I'm sure.
[color=blue]
> As I see it: STest is not a POD (due to string member xyzzy), thus
> the zero initialization does not happen.[/color]
It's different in the 2003 standard.
See http://www.open-std.org/jtc1/sc22/wg...g_defects.html, issue 178. | 
July 22nd, 2005, 03:21 PM
| | | Re: new X vs new X()
Andrew Koenig wrote:[color=blue]
>
> "Karl Heinz Buchegger" <kbuchegg@gascad.at> wrote in message
> news:40DBEAF3.4024FEAE@gascad.at...
>[color=green][color=darkred]
> > > On the other hand, if you write
> > >
> > > STest *p = new STest();
> > >
> > > then p will point to an STest object with its counter member initialized[/color][/color]
> to[color=green][color=darkred]
> > > zero.[/color]
> >
> > Sure about that?[/color]
>
> Yes, I'm sure.
>[color=green]
> > As I see it: STest is not a POD (due to string member xyzzy), thus
> > the zero initialization does not happen.[/color]
>
> It's different in the 2003 standard.
>
> See http://www.open-std.org/jtc1/sc22/wg...g_defects.html, issue 178.[/color]
I see. Item 35 made the intention clear
One exceptional case less.
Thanks for the clearification.
--
Karl Heinz Buchegger kbuchegg@gascad.at | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 220,662 network members.
|