0

In the code base I'm working with there's dozens of header initalized variables:

bool toBeTrue = true;
int var = 1;

And if they're not initialized in the header file they're initialized in the constructor's body:

MyClass::MyClass()
{
 variable1 = 10;
 boolean2 = false;
};

Does initializing the variables in the header file (maybe having pointers initialzed to nullptr, booleans and simple ints in the header file makes sense?) make the compilation time slower? And would moving all the variable initialization moved to the constructor's initialization list make the compilation time faster?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Carrot Cake
  • 57
  • 2
  • 8
  • 3
    Measure the times and tell us. There's no universal catch-all answer. – StoryTeller - Unslander Monica Aug 30 '18 at 07:41
  • @StoryTeller It's better to have an intialization list but I'm not sure about the initalization in the header file – Carrot Cake Aug 30 '18 at 07:43
  • 3
    That thing in the constructor's body is not initialisation, it's assignment. You can only initialise members in the initialiser list. – molbdnilo Aug 30 '18 at 07:44
  • @molbdnilo yup that's right. So without measuring it's probably safe to say that initalization list will result in faster compilation time. – Carrot Cake Aug 30 '18 at 07:46
  • 6
    You can't say anything "safely" about which will compile faster, but the difference in compilation time can be reasonably approximated with zero. The difference in execution time (and semantics) between initialisation and assignment can be substantial, however. – molbdnilo Aug 30 '18 at 07:46
  • The default member initializers are only used *by the constructor* for the case you *don't provide a member initializer* - On the whole, it looks to me like you are engaging with severe premature optimization of something that isn't even likely to be a bottleneck. – StoryTeller - Unslander Monica Aug 30 '18 at 07:47
  • @molbdnilo so what you're saying is that the programme will run faster? – Carrot Cake Aug 30 '18 at 07:50
  • 1
    imho the question is a bit unclear, because you ask for initialization in header vs initializer list, but your code has a third option. Also its not clear if the two snippets are really alternatives, is `toBeTrue` and `var` supposed to be members of some class? – 463035818_is_not_an_ai Aug 30 '18 at 07:51
  • just to repeat it again... you are not using the initializer list in the constructor in the code you show here. First initializing and then assigning is likely to be slower than only initializing – 463035818_is_not_an_ai Aug 30 '18 at 07:53
  • 1
    @CarrotCake No, that's not what I'm saying. The choice between providing an initialiser in the class definition or in an initialiser list will have no effect whatsoever on the speed of your program or its compilation. It's only a matter of convenience. – molbdnilo Aug 30 '18 at 07:53
  • you can take a look at the compiler output with https://godbolt.org/. I doubt there is any difference between in class initialization and initialization list – 463035818_is_not_an_ai Aug 30 '18 at 07:54
  • @CarrotCake Your title does not match your code because your code is not using a constructor initializer list but rather assignment in the constructor body. Please edit one of them to make the question clearer. – acraig5075 Aug 30 '18 at 07:56
  • @CarrotCake On the other hand, the code you posted does not use an initialiser list but first (default-)initialises the variables, and then assigns new values to them. This can have a definite effect on the execution speed. – molbdnilo Aug 30 '18 at 07:58
  • @molbdnilo initalization list is more efficient. Look Effective C++ p.28 paragraph 2 – Carrot Cake Aug 30 '18 at 07:59
  • @CarrotCake effective C++ was written before C++11, ie before it was allowed to initialize non static members in the class declaration. ...and again... p28 compares different things than what you are comparing here – 463035818_is_not_an_ai Aug 30 '18 at 08:08
  • @user463035818 With copy ellision enabled there will be no difference, reference: https://stackoverflow.com/questions/27352021/c11-member-initializer-list-vs-in-class-initializer/27354688 – Carrot Cake Aug 30 '18 at 08:12
  • @CarrotCake I only have a digital edition, so page 28 means nothing to me. If you mean the paragraph that states that initialisation is "often more efficient than assignments" then that's what I've been saying. And Meyers makes no mention of compilation time. (Note that in-class initialisers did not exist when the third edition was published in 2005.) – molbdnilo Aug 30 '18 at 08:15
  • @CarrotCake no difference between what? The edition of the book I found compares initialization+assignment vs initialization on p28. The Q&A you link compares in-class initialization vs initializer list. And it seems like you are still conflating them – 463035818_is_not_an_ai Aug 30 '18 at 08:19
  • 1
    If your intent is to follow good guidelines (a-la Effective C++) then you should consider consulting the C++ Core Guidelines. [This one in particular](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c48-prefer-in-class-initializers-to-member-initializers-in-constructors-for-constant-initializers) is highly relevant. – StoryTeller - Unslander Monica Aug 30 '18 at 08:37

1 Answers1

2

This:

MyClass::MyClass()
{
 variable1 = 10;
 boolean2 = false;
};

is not initialization! The members will be initialized before the body of the constructor runs and then you are assigning values. What you mean is probably the difference between

Initializer list

MyClass::MyClass() : variable1(10), boolean2(false) {}

and in class initialization (available since C++11 I believe) in the header:

struct MyClass {
     int variable1 = 10;
     boolean2 = false;
};

In both the last cases, the values are used to initialize the members, so there is no difference in speed. However, in the first case you are doing more than you actually want to (initialization + assignment) and you should avoid it if possible.

The subtle difference between in-class initialization and initializer list (see eg here) is that

variable1 = 10; 

may involve a copy. This can be circumvented by using direct-list-initialization:

 struct MyClass {
     int variable1{10};
     bool boolean2{false};
};

However, for an int and a bool this wont make any difference whatsoever.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • so C++11 class initialization will result in the compiler creating an initalization list? Could you please link any refernce? – Carrot Cake Aug 30 '18 at 08:05
  • 1
    according to this they're not the same https://stackoverflow.com/questions/27352021/c11-member-initializer-list-vs-in-class-initializer/27354688 – Carrot Cake Aug 30 '18 at 08:07
  • @CarrotCake please read the answer carefully. Concerning speed it says: "With a copy-elision enabled both have identical performance." and then continues to explain how to circumvent that difference. Will edit the answer... – 463035818_is_not_an_ai Aug 30 '18 at 08:11
  • you should probably change the bit "In both the last cases, the values are used to initialize the members, so there is no difference in speed" in your answer since it's contradicting with what you're writing next – Carrot Cake Aug 30 '18 at 08:23
  • @CarrotCake on SO we cannot write most general tutorial that guide you in all cases. We can give you answers for concrete cases / questions. Your question is still a bit difficult to answer concicesly because there are the aforementioned unclarities. If you worry about performance in case of expensive to copy objects then you should post an [mcve] – 463035818_is_not_an_ai Aug 30 '18 at 08:42