0
#include <iostream>

using namespace std;
class Apple
{
    public:
       int i;
       string s = "HelloWorld";
       string s1;
       bool b;
};

int main(int argc, char *argv[]) {
    Apple a; //doesn't this trigger default initialization??
    cout << a.i << a.s << a.s1 << a.b;

}

If the object is a local variable, then the data members will be be default-initialised. But here is the output: 0HelloWorld0. Isn't this value initialization??

ipc
  • 8,045
  • 29
  • 33
tez
  • 4,990
  • 12
  • 47
  • 67
  • 1
    The int and bool are left uninitialized. For example, [this Clang output](http://liveworkspace.org/code/49iU9N%240) shows 4198493 for the int, and removing the unsupported feature, [Intel's compiler](http://liveworkspace.org/code/49iU9N%241) gives 1 for the int and true for the bool. – chris Mar 17 '13 at 19:23
  • Isn't that value initialized?? to 0 ?? – tez Mar 17 '13 at 19:25
  • 2
    No, value-initialized means the int and bool would always be 0 on every conforming compiler. Default means the int and bool are left uninitialized, and the string's default constructor is called (except the one you explicitly initialized). – chris Mar 17 '13 at 19:25
  • Is this a new standard? How can you assign value to non static, const variable in class declaration? – nabroyan Mar 17 '13 at 19:26
  • possible duplicate of [default initialization in C++](http://stackoverflow.com/questions/2224159/default-initialization-in-c) – Bo Persson Mar 17 '13 at 19:33
  • 3
    @nabroyan, the question is tagged C++11, see http://www.stroustrup.com/C++11FAQ.html#member-init – Jonathan Wakely Mar 17 '13 at 19:40
  • 1
    @tez, you have made the mistake of thinking that because you happen to see zeros that the members must have been set to zero. Maybe your computer just has very clean memory that's full of zeros today. Tomorrow it might be full of dead beef. Don't assume that a program isn't buggy just because it doesn't show a spectacular, highly-visible failure. – Jonathan Wakely Mar 17 '13 at 19:44
  • @JonathanWakely thank you. Although it is not compiling in MS Visual Studio 2012, that means, that they don't cover whole C++11 standard. – nabroyan Mar 17 '13 at 19:46

2 Answers2

2

Isn't this value initialization??

On my machine, your program outputs -1219700747HelloWorld244, a clear indicator for default initialisation.

That you get 0HelloWorld0 isn't fully random and can have many reasons. For example, it has something to do with your os architecture. All new memory for each program is initially zeroed, and this is why in this simple example, everything is set to zero. Or the compiler initializes the struct statically for performance reasons.

To quote the standard at 12.6.2/8:

In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then

— if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in 8.5;

— otherwise, if the entity is an anonymous union or a variant member (9.5), no initialization is performed;

— otherwise, the entity is default-initialized (8.5).

ipc
  • 8,045
  • 29
  • 33
  • 1
    Or the compiler is zeroing them, or there are 0s there by chance, or the UB triggered some paradoxical effect, making the output be 0 even though they had a different value :p – chris Mar 17 '13 at 19:28
2

Here's a simple test that indicates no value initialization is being performed in your code.

#include <iostream>
#include <string>

using namespace std;
class Apple
{
    public:
       int i;
       string s = "HelloWorld";
       string s1;
       bool b;
};

int main() 
{
   {
     Apple a; 
     a.i = 42;
     a.b = true;
     cout << a.i << a.s << a.s1 << a.b;
   }
   {
     Apple a; 
     cout << a.i << a.s << a.s1 << a.b;
   }
   {
     Apple a{}; 
     cout << a.i << a.s << a.s1 << a.b;
   }
}

Output:

42HelloWorld142HelloWorld10HelloWorld0

As you can see, in the second case those members still contain values from the previous assignment. Note that I'm not saying this is guaranteed or standard defined behavior.

In the third case you are indicating that the object should be value-initialized by adding the braces.

If your compiler doesn't support C++11's uniform initialization syntax, you can change it to the following to achieve the same effect.

Apple a = Apple();
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • So the synthesized constructor is equivalent to eqlnt to Apple():s("HelloWorld"),s1(){} if default initialised leaving i,b uninitialised , Apple():i(0),s("HelloWorld"),s1(),b(0){} if value initialised – tez Mar 17 '13 at 20:46