3
#include <string>
 
struct T1 { int mem; };
 
struct T2
{
    int mem;
    T2() { } // "mem" is not in the initializer list
};
 
int n; // static non-class, a two-phase initialization is done:
       // 1) zero initialization initializes n to zero
       // 2) default initialization does nothing, leaving n being zero
 
int main()
{
    int n;            // non-class, the value is indeterminate
    std::string s;    // class, calls default ctor, the value is "" (empty string)
    std::string a[2]; // array, default-initializes the elements, the value is {"", ""}
//  int& r;           // error: a reference
//  const int n;      // error: a const non-class
//  const T1 t1;      // error: const class with implicit default ctor
    T1 t1;            // class, calls implicit default ctor
    const T2 t2;      // const class, calls the user-provided default ctor
                      // t2.mem is default-initialized (to indeterminate value)
}

Im currently looking at the reference guide, however there a a few things i don't understand.

I have run the above code, for the struct T2, the data member "int mem" is not in the initialiser list. It is said that t2.mem is default-initialized to an indeterminate value. But when i run this code, t2.mem seems to be zero initialised for me?

drescherjm
  • 10,365
  • 5
  • 44
  • 64
AskJheeze
  • 33
  • 3
  • Zero is a possible indeterminate value, using the value invokes undefined behavior, also see [Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?](https://stackoverflow.com/q/23415661/1708801) also relevent [Is uninitialized local variable the fastest random number generator?](https://stackoverflow.com/q/31739792/1708801) – Shafik Yaghmour Dec 29 '18 at 03:44
  • *But when i run this code, t2.mem seems to be zero initialised for me?* -- It could be 0, 14, -2323, 784, etc. Why single out 0 as not being possible indeterminate value? Second, possibly your compiler (in debug mode) initializes the value to 0. Many compilers will do this, such as Visual Studio. – PaulMcKenzie Dec 29 '18 at 03:57
  • Explains why then, im using VS – AskJheeze Dec 29 '18 at 03:58
  • I would expect it to be initialized to `0xcccccccc` in debug mode of Visual Studio. Edit: I just tested it in VS2017 and `t1.mem` and `t2.mem` were both initialized to `0xcccccccc` as I expected. This link explains that: https://stackoverflow.com/a/127404/487892 – drescherjm Dec 29 '18 at 04:07

1 Answers1

5

But when i run this code, t2.mem seems to be zero initialised for me?

No, in both cases (T1, T2), mem is not initialized, or initialize by indeterminate value. The explicit declaration of the constructor in this case does not affect the mem initialization. If you want to initialize mem, you must do it explicitly in the member initializer list:

struct T2
{
    int mem;
    T2() : mem(0) { }
};

Or through the default member initializer:

struct T1 { int mem = 0; };

Or through aggregate initialization ofT1, which is only takes place if T1 does not have any user declared constructors.

struct T1 { int mem; }

int main() {
    T1 a{}; // aggregate initialization
    assert(a.mem == 0)

    T1 b; // default constructor does not value initialize mem
}

If you see that mem initialized by 0 in the second case, then this is most likely a feature of the compiler, or you just get lucky with the 0 value. This is not guaranteed by the standard, don't rely on it.

Mike Lui
  • 1,301
  • 10
  • 23
Dmytro Dadyka
  • 2,208
  • 5
  • 18
  • 31
  • I dont think you are correct to be honest, t1 and t2 have automatic storage and are initialised to indeterminate values – AskJheeze Dec 29 '18 at 19:11
  • Objects t1 and t2 have automatic storage, subobjects inherit the lifetime of the superobject. They too have automatic storage and are default initialized to indeterminate values – AskJheeze Dec 29 '18 at 20:54
  • @AskJheeze, to be honest, I did not understand your thought. Yes, t1 and t2 are initialised to indeterminate values, that's what i wrote. Yes, subobjects inherit the lifetime of the superobject and default initialized to indeterminate values! – Dmytro Dadyka Dec 30 '18 at 01:01