views:

171

answers:

4

I am currently taking a c++ course and trying to get a deep understanding of the whole thing. I came up with some theories, it would be great if somebody could confirm them:

Every variable (local,global,staic,member and non-member) is guaranteed to have its ctor called before first use

The ctors of primitives like int are essentially no-ops, so we have explicitly assign a value, there is no default zero value.

the following classes are semantically the same (and should generate identical code)

class A 
{ 
  int n; 
};

and

class A 
{
  int n;
 public:
  A() : n() {}
};

and

class A 
{
  int n;
 public:
  A() { n = int(); }
};

The variable n is in every case still uninitialized.

EDIT:

It seem that I absolutetly underestimated the complexity of this subject, most of my assumptions were wrong. Now Iam still trying to find out the basic rules of object initialisation.

+3  A: 

I'm afraid you are wrong. When you say:

int n = int();

Then n (and all other POD types) will zero initialised.

Also, make sure that you are very clear in your mind about the difference between initialisation and assignment - this is quite important in C++:

int n = int();    // initialisation
n = 0;            // assignment
anon
+3  A: 

You might find this interesting.

The difference between new Foo and new Foo() is that former will be uninitialized and the latter will be default initialized (to zero) when Foo is a POD type. So, when not using the form with the parens, the member "a" can contain garbage, but with the parens "a" will always be initialized to 0.

kitchen
I find this statement hard to believe. class Bar { int n; } is a POD because it's implicitly-defined ctor is /trivial/ (formal term from ISO). Yet, it exists, and both `new Bar;` and `new Bar()` call it. In neither case will Bar::Bar() initialize Bar::n
MSalters
"class B {int n;};" is *not* a POD because it contains a private non-static member 'n'. However, if it was defined as "class B { public: int n; };" then it would be a POD, and so 'n' will be value-initialized when you do "new Bar()".
Richard Corden
Is it even possible for a newbie to fully understand this subject? There seem to be so many rules and exceptions :-(
codymanix
+1  A: 

No, the variable is only left uninitialised in the first case.

For a member that is a class with a user-defined constructor, the situation is simple: a constructor is always called.

Built-in types (and 'plain old data' structs) may be left uninitialised, as in your first example. Although they don't have user-supplied constructors, using the construction syntax (your other two examples) initialises them to zero.

The reason for this slightly tricky rule is to avoid undue overhead; for example if you defined:

struct S { int array[1024*1024]; };

with the intention of only assigning values as you needed them, you wouldn't want the compiler to whitewash 4Mb of memory with zeroes whenever you construct one.

James Hopkin
This is hillarious, it is much more complicated than I thought. If I create an empty ctor A(){}, then the variable n is initialized! I always thought that when you have an empty ctor it is the same as having no ctor (which implicity will create a default ctor), so my 1st and 4rd classes should be identical, but they aren't.
codymanix
That sounds wrong. Are you using an old version of GCC? Also, you should state where you are creating the instance of A: I'm assuming on the stack or heap. If it's a static object, the members will be initialised to zero before the constructor is called (this is called 'value initialisation', if you want to Google for it).
James Hopkin
+1  A: 

class A { int n; }; Only memory is allocated, no initialization done for n.


class A { int n; public: A() : n() {} }; Here n is initialized with 0.


class A { int n; public: A() { n = int(); } }; Here n is first constructed (without any default value), then int() causes a temp int to be created with value 0 Which is then assigned to n;

Very strange. I was sure that I once had the second version with A():n(){} in a project of mine and it caused n not to be initialized. I used GCC though. Could this be compiler dependent?
codymanix
@codymanix. No this is standard behavior. Though I believe in the first version of the standard this was not specified because who would do such a thing!!! So your observations may be true for a very old compiler.
Martin York