Re: C++ Compiler behavior regarding struct constructors

From: Carl Daniel [VC++ MVP] (cpdaniel_remove_this_and_nospam_at_mvps.org.nospam)
Date: 12/19/04


Date: Sun, 19 Dec 2004 08:29:00 -0800

Karl M wrote:
> Hi everyone,
> I just notice some strange behaviors on the MS C++ compiler regarding
> struct default constructor

You're just not used to the initialization rules for C++ (which are arcane
and obscure).

When you write...

int a[5];

...the contents of a[] are undefined.

Likewise...

struct Z
{
   int a[5];
};

Z z;

...the contents of z are undefined.

8.5/9 of the C++ standard says

<quote>
If no initializer is specified for an object, and the object is of (possibly
cv-qualified) nonPOD 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 an object, the object and its
sub-objects, if any, have an indeterminate initial value; if the object or
any of its sub-objects are of const-qualified type, the program is
ill-formed.
</quote>

You're falling afoul of the "Otheriwse..." part of that quotation.

> struct MyStruct
> {
> int a[5];
> };
> class MyClass
> {
> public:
> MyClass();
> ~MyClass();
> protected:
> MyStruct m_MyStruct;
> };
> //#1:
> MyClass::MyClass() //The default ctor for the class does not init the
> struct with NULL(maybe there is no default ctor for struct yet?)
> {

Here m_MyStruct has undefined content because MyStruct is a POD (which
implies no user defined constructors) so it's not initialized.

> }
> //#2 if I define the class ctor like this:
> MyClass::MyClass() : m_MyStruct() //The default ctor for the class
> does init the struct with NULL(call m_MyStruct() default ctor, now
> there is one!) {

Correct. Since you've forced the creation of a default contructor for
MyStruct, that default constructor zero-fills the memory.

> }
> //#3 or like this:
> MyClass::MyClass()
> {
> m_MyStruct = MyStruct(); // dose init the struct with NULL using a
> local stack var init with NULL

Likewise, you've forced the creation (and calling) of a default constructor
for MyStruct() which zero-fills the memory.

> }
> //Now if I define the struct like this:
> struct MyStruct
> {
> MyStruct()
> {
> int i;
> for(i=0;i<5;i++)
> a[i] = NULL;
> }
> int a[5];
> };

This is equivalent to the default constructor that the compiler will
generate for you, so it shouldn't be surprising that the results are nearly
identical.

> //#1 will init the struct with NULL because uses the defined struct
> ctor but generate almost the same bin (asm) code as case #2 and #3
> (the init stack var) without the struct ctor defined!
> I guess I don't understand when the compiler knows about the struct
> default constructor and when dose not (and expect for one defined).

It always knows about it, your example #1 simply doesn't force the compiler
to explicitly create a default constructor. Getting back to the quote from
8.5 of the standard - once you force a struct to have a constructor, it's no
longer a POD, so the code falls under the first sentence of that passage -
the object is default-initialized.

The best advice is: if you need initialization, write a constructor.

HTH

-cd



Relevant Pages

  • Re: How to initialize a member struct
    ... I can't give this struct a constructor. ... class constructor (call it "TemplatedClass") in another DLL library. ... This leaves me with trying to come up with a way to initialize ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Initializing a class field of a custom struct type?
    ... ::: Apart what it is (assignment and not initialization), ... :: constructor, then make default constructor for `MYSTRUCT': ... struct, so you are not allowed to use memset on it! ... class member) to copy from: ...
    (microsoft.public.vc.language)
  • Re: C++ user-defined new (expert question)
    ... I don't see here a reason to put the default/non-default constructor into ... typedef struct { ... MYPOINT * MYPOINT_new ... void MYPOINT_free ...
    (microsoft.public.vc.mfc)
  • Re: TREE structure in MFC, how, where and why?
    ... Your struct contains a CString object, which is a C++ class with various ... By using malloc, the constructor on your CString is not being called. ...
    (microsoft.public.vc.mfc)
  • Re: remove structs default constructor?
    ... any use of a struct to use my constructor, ... what the constructor forces them to be. ... neither implied nor explicit. ... initializing MyStruct z, just some code that runs to generally ...
    (microsoft.public.dotnet.languages.csharp)