"Default construction" of built-in types?

D

DaKoadMunky

I recently came across some code in a template that default constructed an
object of type T to pass to another function...

SomeFunction(T());

The code that instantiates that template specifies T as an int.

Proper program behavior relies on that "default constructed" int being zero.

That lead me to the following example...

int main()
{
int i; //Uninitialized! Expected for automatic of built-in type

int j = int(); //Initialized to zero! Not sure what to expect

return 0;
}

Is such "default construction" of built-in types standard C++?

char() == 0
int()==0

etc...

Thanks
 
V

Victor Bazarov

DaKoadMunky said:
I recently came across some code in a template that default constructed an
object of type T to pass to another function...

SomeFunction(T());

The code that instantiates that template specifies T as an int.

Proper program behavior relies on that "default constructed" int being
zero.

"Default-initialised" is the proper term. And, yes, it is supposed to be
initialised to zero.
That lead me to the following example...

int main()
{
int i; //Uninitialized! Expected for automatic of built-in type

int j = int(); //Initialized to zero! Not sure what to expect

What do you mean by the second part of the comment?
return 0;
}

Is such "default construction" of built-in types standard C++?

Yes.

Victor
 
D

DaKoadMunky

int j = int(); //Initialized to zero! Not sure what to expect
What do you mean by the second part of the comment?

Comment could have been extended to say "on other compilers, platforms, etc.."
given that I didn't know if the initialization to zero was standard.
 
A

Alan Johnson

Victor said:
zero.

"Default-initialised" is the proper term. And, yes, it is supposed to be
initialised to zero.




What do you mean by the second part of the comment?




Yes.

Victor

I didn't believe you, so I looked it up, and sure enough, that is correct.

To the OP:
The standard says that any object whose initializer is () is
"value-initialized", and for POD types, "value-initialized" is defined
as being "zero-initialized". Refer to Section 8.5 for more info.

Alan
 
R

Robbie Hatley

Alan Johnson said:
The standard says that any object whose initializer is () is
"value-initialized", and for POD types, "value-initialized" is defined
as being "zero-initialized". Refer to Section 8.5 for more info.

Ah-ha! I ran into trouble at work with a struct which
I had instantiated inside a function like so:

MyStruct Blat;

The struct had an int member which I expected to be
initialized to 0, but it actually had an initial value
of 512 !

So you're saying if I had instantiated it like this, instead:

MyStruct Blat ();

The numerical members would be initialized to 0 ?

--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 
P

Phlip

So you're saying if I had instantiated it like this, instead:
MyStruct Blat ();

The numerical members would be initialized to 0 ?

That sez "Blat is a function that returns MyStruct".

You need thus:

MyStruct Blat = MyStruct ();

or

MyStruct Blat (MyStruct ());

This otherwise silly system exists so STL containers can default-construct
primitives without leaking garbage into them.

int x;

The act of using 'x' is now undefined for most operations except assignment.
 
A

Alf P. Steinbach

* "Robbie Hatley said:
Ah-ha! I ran into trouble at work with a struct which
I had instantiated inside a function like so:

MyStruct Blat;

The struct had an int member which I expected to be
initialized to 0, but it actually had an initial value
of 512 !

So you're saying if I had instantiated it like this, instead:

MyStruct Blat ();

The numerical members would be initialized to 0 ?

With a compiler that conforms in this respect, yes.

It is not a feature you can rely on, though.

Please stop changing the subject line, as it messes up the threading in
most newsreaders.
 
R

Robbie Hatley

Phlip said:
That sez "Blat is a function that returns MyStruct".

OOPS! Right, that's a prototype that says "I'll be
defining a function Blat later that takes no arguments and
returns a MyStruct". I really missed that one.
You need thus:

MyStruct Blat = MyStruct ();

or

MyStruct Blat (MyStruct ());

I don't like those.

The first one calls two constructors instead of just one:

MyStruct Blat = MyStruct (); // Default + Assignment

As for the second one:

MyStruct Blat (MyStruct ());

That compiles, but yields a function, not an object.
I think you you just declared a function which returns
a MyStruct, and takes as an argument a nameless pointer
to a nameless function which takes no arguments and
returns a MyStruct. Not a very useful concept. :)

I think I like the approach I ended up using, after all:

MyStruct
{
MyStruct () : asdf(0), qwer(0) {}
int asdf;
int qwer;
};

int main(void)
{
MyStruct Blat; // Zeros members; calls only one constructor
}


--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 
T

tom_usenet

I don't like those.

The first one calls two constructors instead of just one:

MyStruct Blat = MyStruct (); // Default + Assignment

You meant default and copy. But all compilers I know of elide the
temporary (as is allowed by the standard) and therefore don't make the
copy.
As for the second one:

MyStruct Blat (MyStruct ());

That compiles, but yields a function, not an object.

You need:

MyStruct Blat ((MyStruct()));

which is getting silly...
I think I like the approach I ended up using, after all:

MyStruct
{
MyStruct () : asdf(0), qwer(0) {}
int asdf;
int qwer;
};

int main(void)
{
MyStruct Blat; // Zeros members; calls only one constructor
}

Yup, that's the best plan, but in generic code where you want default
initialization but don't know the type, you should probably do:

T t = T();

Tom
 
P

Phlip

tom_usenet said:
You need:

MyStruct Blat ((MyStruct()));

which is getting silly...

I suspect you both have that one wrong.

MyStruct Blat ((MyStruct())); can't be different from MyStruct Blat
(MyStruct()); or MyStruct Blat ((((((((MyStruct()))))))));. Many types can
take extra parens.

MyStruct() is an rvalue, so the compiler sees Blat's input argument, not a
type for a function.

BTW use T t = T(), just as a style guideline.
 
R

Rob Williscroft

Phlip wrote in in
comp.lang.c++:
I suspect you both have that one wrong.

MyStruct Blat ((MyStruct())); can't be different from MyStruct Blat
(MyStruct()); or MyStruct Blat ((((((((MyStruct()))))))));. Many types
can take extra parens.

(int a); // not a legal declaration.
int (a); // legal.

MyStruct() is an rvalue, so the compiler sees Blat's input argument,
not a type for a function.

BTW use T t = T(), just as a style guideline.

Yup.

Rob.
 
X

Xenos

tom_usenet said:
You meant default and copy. But all compilers I know of elide the
temporary (as is allowed by the standard) and therefore don't make the
copy.

It was always my understanding that, even though this looks like an
assignment, it is not. It is still just a constructor call in another form.
Any talk of the compiler optimizing away the assignment is moot.

DrX
 
R

Richard Herring

Xenos said:
It was always my understanding that, even though this looks like an
assignment, it is not. It is still just a constructor call in another form.
Any talk of the compiler optimizing away the assignment is moot.
Maybe so, but talk of the compiler optimizing away the
_copy-construction_ (12.8.15) is perfectly valid ;-).
 

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,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top