Initializers

Discussion in 'C++' started by Michael Tsang, Apr 19, 2010.

  1. I'm very confused among different types of initializations:

    zero-initialize:
    scalar: set to 0
    class/array: initialize recursively
    union: initialize first member
    reference: no-op

    default-initialize:
    class: call default constructor
    array: initialize recursively
    reference: ill-formed
    others: no-op

    value-initialize:
    class with user-provided constructor: call default constructor
    non-union class without user-provided constructor: zero-
    initialise and call non-trivial constructor
    array: initialize recursively
    reference: ill-formed
    others: zero-initialize

    implicitly-defined default constructor:
    default-initialize base classes and members recursively

    When the direct initializer is (), the object is value-initialized but
    consider the following:

    #include <iostream>
    struct A
    {
    A()
    {
    std::cout << "test" << std::endl;
    }
    int x;
    };

    struct B
    {
    // non-trivial implicit default constructor
    A a;
    int x;
    };

    A x; // x is zero-initialized and then default initialized so that x.x
    == 0

    int main()
    {
    A *p = new A; // p->x is not determined.
    A *q = new A(); // q->x is also not determined?! A
    standard caveat?!
    delete p;
    delete q;
    B *r = new B; // default-initialized recursively: s->x
    and s->a.x are both indeterminate.
    B *s = new B(); // zero-initialized first: s->x and s->a.x
    are both 0
    }

    Also, how does zero-initializing a reference make sense?
    Michael Tsang, Apr 19, 2010
    #1
    1. Advertising

  2. Victor Bazarov wrote:

    > Michael Tsang wrote:
    >> I'm very confused among different types of initializations:
    >>
    >> zero-initialize:
    >> scalar: set to 0
    >> class/array: initialize recursively
    >> union: initialize first member
    >> reference: no-op

    >
    > Huh? Where do you get the "no-op"?
    >
    >>
    >> default-initialize:
    >> class: call default constructor
    >> array: initialize recursively
    >> reference: ill-formed
    >> others: no-op
    >>
    >> value-initialize:
    >> class with user-provided constructor: call default constructor
    >> non-union class without user-provided constructor: zero-
    >> initialise and call non-trivial constructor
    >> array: initialize recursively
    >> reference: ill-formed
    >> others: zero-initialize
    >>
    >> implicitly-defined default constructor:
    >> default-initialize base classes and members recursively
    >>
    >> When the direct initializer is (), the object is value-initialized but
    >> consider the following:
    >>
    >> #include <iostream>
    >> struct A
    >> {
    >> A()
    >> {
    >> std::cout << "test" << std::endl;
    >> }
    >> int x;
    >> };
    >>
    >> struct B
    >> {
    >> // non-trivial implicit default constructor
    >> A a;
    >> int x;
    >> };
    >>
    >> A x; // x is zero-initialized and then default initialized so that x.x
    >> == 0
    >>
    >> int main()
    >> {
    >> A *p = new A; // p->x is not determined.
    >> A *q = new A(); // q->x is also not determined?! A
    >> standard caveat?!

    >
    > Why is that a caveat? If you provide the default constructor and
    > *purposefully* omit 'x' from the initializer list, it's left
    > uninitialized no matter whether you use parens here or not.
    >
    >> delete p;
    >> delete q;
    >> B *r = new B; // default-initialized recursively: s->x
    >> and s->a.x are both indeterminate.
    >> B *s = new B(); // zero-initialized first: s->x and s->a.x
    >> are both 0

    >
    > Zero-initialized first? Where do you get that? It's not static.

    I got it from the latest draft (N3092).
    >
    > The dynamic B object is value-initialized, yes (see 5.3.4/15)? And
    > since 'B' is an aggregate (no user-defined c-tors, no private or
    > protected non-static members, no virtual functions, no base classes), to
    > value-initialize it means that every non-static member and every base
    > class is value-initialized. And since 'A' has a user-defined c-tor, to
    > value-initialize it means to call that c-tor.
    >
    > So, nope. Since 'A' has a user-declared c-tor, s->a.x is still
    > uninitialized!
    >
    >> }
    >>
    >> Also, how does zero-initializing a reference make sense?

    >
    > There ain't no such a thing as "zero-initializing a reference".

    The document does mention zero-initializing a reference.
    >
    > V
    Michael Tsang, Apr 20, 2010
    #2
    1. Advertising

  3. Michael Tsang

    tonydee Guest

    On Apr 20, 11:41 am, Michael Tsang <> wrote:
    > Victor Bazarov wrote:
    > > Michael Tsang wrote:
    > >> I'm very confused among different types of initializations:


    Don't make it too complex. The important thing is just that your
    constructor should explicitly populate the values to get the class
    into a good state - unless they have adequate default constructors
    themselves (e.g. STL containers) - and assume anything else will be
    indeterminate. That's ok if the indeterminate value(s) will
    definitely be written to before being read.

    Cheers,
    Tony
    tonydee, Apr 20, 2010
    #3
  4. * Michael Tsang:
    > I'm very confused among different types of initializations:


    [snip]

    All that you need to remember and that you can rely on is

    * Static duration objects are zero initialized before anything else.

    * Apart from that, you get the initialization that you specify.

    E.g. if you have defined at least one constructor for your class, then a
    constructor will be called for every instance of that class (except if one does
    nasty low-level things).

    And e.g., when you write

    T* const p = new T();

    then the parenthesis says that you want initialization, and for each member of T
    you get the initialization that is available (zeroing or a constructor call).

    If you omit the parenthesis then you say that you don't care about
    initialization and that you will be happy with whatever initialization that T
    defines, if any.


    > }
    >
    > Also, how does zero-initializing a reference make sense?


    The standard defines it thusly, in §8.5/5: "no initialization is performed".

    It's that simple.

    Of course since you can't use the reference without UB before it's been properly
    initialized, a compiler may choose to represent a namespace level reference as a
    pointer and zero the pointer value so that &r, if it didn't do any of all the
    arbitrary things that the UB allows, would yield a null-pointer at this time.


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Apr 20, 2010
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Glen Able

    Class variable initializers

    Glen Able, Jan 29, 2004, in forum: Java
    Replies:
    0
    Views:
    334
    Glen Able
    Jan 29, 2004
  2. j l
    Replies:
    5
    Views:
    395
    A. Bolmarcich
    Feb 23, 2004
  3. James Robert Leek

    JNI Invocation: static UN-initializers?

    James Robert Leek, Aug 31, 2004, in forum: Java
    Replies:
    2
    Views:
    487
    James Robert Leek
    Aug 31, 2004
  4. HK
    Replies:
    7
    Views:
    418
    Wibble
    May 30, 2005
  5. HK
    Replies:
    3
    Views:
    4,167
Loading...

Share This Page