I got a question about default constructor, let's see:
///////////
#include <vector>
struct Point
{
float x, y, z;
};
void test()
{
Point p0;
Point p1 = Point();
std::vector<Point> vec_p(100);
}
//////////////
I tested the result in vs2008, data members of p0 was not initialized
which was just as I know. But all member of p1 was initialized as
0.0f, as well as all points in vec_p were initialized as (0.0f, 0.0f,
0.0f). I got that the constructor of std::vector with a size parameter
would initialize all data as default value which called Point() as
well. Here is my question why Point() initialized all member of Point
as 0? Is it vs2008 specified or c++ specification?
Thanks anyone helping on this.
- AskQ
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
I can't relly give an answer.
Two points however:
* I've tried it with VS2008 "Disable Lang Ext = Yes" and it still is done.
* If you add a destructor (sic!) to the struct, the behaviour will
disappear, ie. the members will always stay uninitialized.
Probably it's got to do with POD initializing behaviour, i.e. when you
write int i = int(); you'll get a zero whereas int j; will be
uninitialized ... and your simple Point is a POD after all. (the one
with the dtor apparently isn't)
br,
Martin
All the members of Point is initialized to 0 because below statement:
Point p1 = Point();
is same as
Point p1 = Point(0);
Point(0) ensures that all its members are initialized to zero.
In C++, 0 is considered as universal initializer, and its applicable
for all data types.
-Kailash
The C++ Standard specifies that Point() has its all its data members
zero-initialized, so it's great that vs2008 is doing so. (I assume you
mean MSVC!) Actually the C++ Standard goes even further, as it /even/
requires Point() to have its float members zero-initialized if it has
some other data member(s), having a user-declared default constructor
(for example std::string):
struct Point2
{
std::string s;
float x, y, z;
};
Unfortunately, in that case MSVC 2008 doesn't follow the C++ Standard,
as MSVC may leave the float data members of Point2() uninitialized. As
was reported by Pavel Kuznetsov, "Value-initialization in
new-expression":
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
But honestly MSVC isn't the only compiler that hasn't entirely
implemented value-initialization. If you want to be sure that your data
is correctly value-initialized, you might consider using Fernando
Cacciola's boost::value_initialized, as Fernando and I provided a
workaround to those compiler bugs :-)
http://www.boost.org/libs/utility/value_init.htm
HTH, Niels
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center
Yes, that is Standard specified behavior.
This is plain wrong. 0 is by no means a "universal initializer" (in
fact, there's no such thing at all), and Point(0) in the above example
won't even compile for a POD type Point.
The behavior you see is required by the C++ standard. Point struct is
a POD (Plain Old Data) type - you can see the spec for a full
definition of POD, but any C-style struct definition with only public
data members of POD or fundamental types will fit. Here's what the
standard says about initialization of objects:
8.5[dcl.init]/5:
"To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0
(zero) converted to T;
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for
T is called (and the initialization is ill-formed if T has no
accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the object is zero-initialized.
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;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized"
8.5[dcl.init]/7:
"An object whose initializer is an empty set of parentheses, i.e., (),
shall be value-initialized."
8.5[dcl.init]/9:
"If no initializer is specified for an object, and the object is of
(possibly cv-qualified) non-POD class type (or array thereof), the
object shall be default-initialized; if the object is of const-
qualified type, the underlying class type shall have a user-declared
default constructor. Otherwise, if no initializer is specified for a
nonstatic object, the object and its subobjects, if any, have an
indeterminate initial value;"
In your case, p0 is a nonstatic object with no initializer, and so it,
and all its subobjects (x, y, z) have an indeterminate initial value.
On the other hand, p1 is initialized with a temporary, which in turn
has initializer (), which requires it to be value-initialized - for a
POD struct, this means that all subobjects (x, y, z) are value-
initialized, and for them it is the same as being zero-initialized.
> void test()
> {
> Point p0;
> Point p1 = Point();
> std::vector<Point> vec_p(100);}
>
> //////////////
>
> I tested the result in vs2008, data members of p0 was not initialized
> which was just as I know. But all member of p1 was initialized as
> 0.0f, as well as all points in vec_p were initialized as (0.0f, 0.0f,
> 0.0f).
And that is the expected behaviour.
I'm not sure about the exact terms, but here are what to expect when
dealing with PODs:
T a; // unspecified initialization
T b = T(); // zero-initialized
T* c = new T; // unspecified initialization
T* d = new T(); // zero-initialized
All standard containers will ensure that their elements are properly
initialized.
Pavel Minaev schrieb:
> This is plain wrong. 0 is by no means a "universal initializer" (in
> fact, there's no such thing at all),
I guess Kailash was referring to a different way to initialize a struct
without user defined constructors:
Point p = {0};
Here the zero looks like a "universal initializer". In fact it only
initializes the first float of Point. And because further initializers
are missing, the remaining floats get zero-initialized. Which leads to:
Point p = {}; //zero init for all members
Obviously the same.
Frank