Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does in class member initialization takes place at compile time or run-time?

Tags:

c++

c++11

In C++11 a new feature was introduced where the programmer can initialize class member variables inside class's definition, see code below:

struct foo
{ 
  int size = 3;
  int id   = 1;
  int type = 2;
  unsigned char data[3] = {'1', '2', '3'};
};

Is this initialization takes place during compile time or this feature is just syntactic sugar and member variables are initialized in the default constructor?

like image 660
101010 Avatar asked Apr 21 '14 22:04

101010


3 Answers

First of all yes, as stated before, it is syntactic sugar. But since the rules can be too much to remember, here's a logical experiment to help you figure out what happens in compile time and what not

You have your c++11 class that features in class initializers

struct foo { int size = 3; };

And another class that will help us with our experiment

template<int N>
struct experiment { enum { val = N }; };

Let our hypothesis H0 be that initialization does happen in compile time, then we could write

foo                a;
experiment<a.size> b;

No luck, we fail to compile. One could argue that failure is due to foo::size being non constant so lets try with

struct foo { const int size = 3; }; // constexpr instead of const would fail as well

Again, as gcc informs us

the value of ‘a’ is not usable in a constant expression

experiment b;

or (more clearly) visual studio 2013 tells us

error C2975: 'N' : invalid template argument for 'example', expected compile-time constant expression

So, we have to discard H0 and deduce that initialization does not happen in compile time.

What would it take to happen in compile time

There is an old syntax that does the trick

struct foo { static const int size = 3; };

Now this compiles but beware this is (technically and logically) no longer in class initialization.

I had to lie for a little to make a point, but to expose the whole truth now : Message errors imply that a is the real problem. You see, since you have an instance for an object (Daniel Frey also mentions this) memory (for members) has to be initialized (at runtime). If the member was (const) static, as in the final example, then it's not part of the subobjects of a(ny) class and you can have your initialization at compile time.

like image 95
Nikos Athanasiou Avatar answered Oct 17 '22 07:10

Nikos Athanasiou


In-class initialisers for member-variables are syntactic sugar for writing them in the constructor initialiser list, unless there's an explicit initialiser already there, in which case they are ignored.
In-class initialisers of static const members are for constant literals, a definition is still needed (though without initialiser).

C++ has the "as if"-rule from C, so anything resulting in the prescribed observed behavior is allowed.
Specifically, that means static objects may be initialised at compile-time.

like image 28
Deduplicator Avatar answered Oct 17 '22 07:10

Deduplicator


It's just syntactic sugar. Also consider that an instance usually means memory which has to be initialized with the correct values. Just because these values are provided with a different syntax does not change the fact that the memory needs to be initialized - which happens at run-time.

like image 2
Daniel Frey Avatar answered Oct 17 '22 07:10

Daniel Frey