Should pointer members be zero initialized by default?

S

Steven T. Hatton

I mistakenly set this to the comp.std.c++ a few days back. I don't believe
it passed the moderator's veto - and I did not expect or desire anything
different. But the question remains:

ISO/IEC 14882:2003(E) §8.5 says:

  To zero-initialize an object of type T means:
5
  -- if T is a scalar type (3.9), the object is set to the value of 0 (zero)
converted to T;
  -- if T is a non-union class type, each nonstatic data member and each
base-class subobject is zero-
     initialized;
  -- if T is a union type, the object's first named data member89) is
zero-initialized;
  -- if T is an array type, each element is zero-initialized;
  -- if T is a reference type, no initialization is performed.
  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.

I take this to mean that pointers are by default zero-initialized.  Is this
a correct understanding?  Would you rely on this to be the case when you
construct a class with pointer members?  I will probably always initialize
all pointer explicitly, but I'm not sure what I should expect if I don't. 
My observations have been that they don't always behave as I expect when I
don't initialize them explicitly.

I've found it surprizingly difficult to find a direct discussion of this
topic in the resources I have available.
 
K

Kai-Uwe Bux

Steven said:
I mistakenly set this to the comp.std.c++ a few days back. I don't
believe it passed the moderator's veto - and I did not expect or desire
anything
different. But the question remains:

ISO/IEC 14882:2003(E) §8.5 says:

To zero-initialize an object of type T means:
5
-- if T is a scalar type (3.9), the object is set to the value of 0 (zero)
converted to T;
-- if T is a non-union class type, each nonstatic data member and each
base-class subobject is zero-
initialized;
-- if T is a union type, the object's first named data member89) is
zero-initialized;
-- if T is an array type, each element is zero-initialized;
-- if T is a reference type, no initialization is performed.
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.

I take this to mean that pointers are by default zero-initialized. Is
this a correct understanding?  Would you rely on this to be the case when
you construct a class with pointer members?  I will probably always
initialize all pointer explicitly, but I'm not sure what I should expect
if I don't. My observations have been that they don't always behave as I
expect when I don't initialize them explicitly.

I've found it surprizingly difficult to find a direct discussion of this
topic in the resources I have available.

Hm,

you looked up the *definitions* of zero-initialization and
default-initialization. It is true that the default-initialization for
pointers is by zero-initialization. So now, we know *what
default-initialization is*. However, that does not actually answer the
question *when default-initialization will happen*. Here is what the
standard says about that:


[8.5/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 non-static object, the
object and its subobjects, if any, have an indeterminate initial
value[*]; if the object or any of its subobjects are of const-qualified
type, the programm is ill-formed.

[*] This does not apply to aggregate objects with automatic storage
duration initialized with an incomplete brace-enclosed initializer-list;
see 8.5.1.


Thus, for the code

{
int* int_ptr;
...
}

I would expect no default-initialization.


Best

Kai-Uwe Bux
 
S

Steven T. Hatton

Kai-Uwe Bux said:
Steven said:
I mistakenly set this to the comp.std.c++ a few days back. I don't
believe it passed the moderator's veto - and I did not expect or desire
anything
different. But the question remains:

ISO/IEC 14882:2003(E) §8.5 says:

To zero-initialize an object of type T means:
5
-- if T is a scalar type (3.9), the object is set to the value of 0
(zero) converted to T;
-- if T is a non-union class type, each nonstatic data member and each
base-class subobject is zero-
initialized;
-- if T is a union type, the object's first named data member89) is
zero-initialized;
-- if T is an array type, each element is zero-initialized;
-- if T is a reference type, no initialization is performed.
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.

I take this to mean that pointers are by default zero-initialized. Is
this a correct understanding?  Would you rely on this to be the case when
you construct a class with pointer members?  I will probably always
initialize all pointer explicitly, but I'm not sure what I should expect
if I don't. My observations have been that they don't always behave as I
expect when I don't initialize them explicitly.

I've found it surprizingly difficult to find a direct discussion of this
topic in the resources I have available.

Hm,

you looked up the *definitions* of zero-initialization and
default-initialization. It is true that the default-initialization for
pointers is by zero-initialization. So now, we know *what
default-initialization is*. However, that does not actually answer the
question *when default-initialization will happen*. Here is what the
standard says about that:


[8.5/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 non-static object, the
object and its subobjects, if any, have an indeterminate initial
value[*]; if the object or any of its subobjects are of const-qualified
type, the programm is ill-formed.

[*] This does not apply to aggregate objects with automatic storage
duration initialized with an incomplete brace-enclosed initializer-list;
see 8.5.1.


Thus, for the code

{
int* int_ptr;
...
}

I would expect no default-initialization.


Best

Kai-Uwe Bux

I guess I didn't word my question as clearly as I thought. I was explicitly
intended pointers that are members of classes. As I read the paragraph
above, classes should be default initialized if no initializer is
specified. I guess the rub come when I do initialize the class, but I
don't have an explicit initialization for the pointer member. But that
still seems incorrect because the pointer member falls into the "otherwise"
category of 8.5.
--
"I suspect my dislike for the preprocessor is well known. Cpp is essential
in C programming, and still important in conventional C++ implementations,
but it is a hack, and so are most of the techniques that rely on it. ... I
think the time has come to be serious about macro-free C++ programming." -
Bjarne Stroustrup
 
S

Steven T. Hatton

Steven said:
Kai-Uwe Bux said:
Steven said:
I mistakenly set this to the comp.std.c++ a few days back. I don't
believe it passed the moderator's veto - and I did not expect or desire
anything
different. But the question remains:

ISO/IEC 14882:2003(E) §8.5 says:

To zero-initialize an object of type T means:
5
-- if T is a scalar type (3.9), the object is set to the value of 0
(zero) converted to T;
-- if T is a non-union class type, each nonstatic data member and each
base-class subobject is zero-
initialized;
-- if T is a union type, the object's first named data member89) is
zero-initialized;
-- if T is an array type, each element is zero-initialized;
-- if T is a reference type, no initialization is performed.
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.

I take this to mean that pointers are by default zero-initialized. Is
this a correct understanding?  Would you rely on this to be the case
when you construct a class with pointer members?  I will probably always
initialize all pointer explicitly, but I'm not sure what I should expect
if I don't. My observations have been that they don't always behave as I
expect when I don't initialize them explicitly.

I've found it surprizingly difficult to find a direct discussion of this
topic in the resources I have available.

Hm,

you looked up the *definitions* of zero-initialization and
default-initialization. It is true that the default-initialization for
pointers is by zero-initialization. So now, we know *what
default-initialization is*. However, that does not actually answer the
question *when default-initialization will happen*. Here is what the
standard says about that:


[8.5/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 non-static object, the
object and its subobjects, if any, have an indeterminate initial
value[*]; if the object or any of its subobjects are of const-qualified
type, the programm is ill-formed.

[*] This does not apply to aggregate objects with automatic storage
duration initialized with an incomplete brace-enclosed initializer-list;
see 8.5.1.


Thus, for the code

{
int* int_ptr;
...
}

I would expect no default-initialization.


Best

Kai-Uwe Bux

I guess I didn't word my question as clearly as I thought. I was
explicitly
intended pointers that are members of classes. As I read the paragraph
above, classes should be default initialized if no initializer is
specified. I guess the rub come when I do initialize the class, but I
don't have an explicit initialization for the pointer member. But that
still seems incorrect because the pointer member falls into the
"otherwise" category of 8.5.

I started thinking this over again, and realized this is discussed in
§10.4.2 of TC++PL(SE), and that is rather explicit in saying the built-in
types will not be initialized. My confusion had to do with what a
POD-class is.

§9/4 "A POD-struct is an aggregate class that has no non-static data members
of type non-POD-struct, non-POD-union (or array of such types) or
reference, and has no user-defined copy assignment operator and no
user-defined destructor. Similarly, a POD-union is an aggregate union that
has no non-static data members of type non-POD-struct, non-POD-union (or
array of such types) or reference, and has no userdefined copy assignment
operator and no user-defined destructor. A POD class is a class that is
either a POD-struct or a POD-union."

I had mistakenly understood any object of class type to be non-POD.

I had forgotten this from §3.9/10: "Arithmetic types (3.9.1), enumeration
types, pointer types, and pointer to member types (3.9.2), and cvqualified
versions of these types (3.9.3) are collectively called scalar types.
Scalar types, POD-struct types, POD-union types (clause 9), arrays of such
types and cv-qualified versions of these types (3.9.3) are collectively
called POD types."

Now I understand that I should _not_ expect a pointer member to be
zero-initialized by default.
 
S

Siemel Naran

Steven T. Hatton said:
I take this to mean that pointers are by default zero-initialized. Is this
a correct understanding? Would you rely on this to be the case when you
construct a class with pointer members? I will probably always initialize
all pointer explicitly, but I'm not sure what I should expect if I don't.
My observations have been that they don't always behave as I expect when I
don't initialize them explicitly.

Pointers that are local variables are not zero initialized. Same holds for
pointers that are member variables of local objects (ie. objects created on
the function stack or created with new).

Pointers that are class static, function static, global, or namespace
variables are zero initialized. I think the same holds for pointers that
are member variables of class static, function static, global, or namespace
objects.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top