23

I have a situation like this:

class A {
public:
  A() : n(0) {}
private:
  int n;
  int m;
}

There is simply no meaning in the application logic to initialize m in the constructor. However, Eclipse warns me that the constructor leaves m uninitialized. I can't run the code somewhere else now. The warning is:

Member 'm' was not initialized in this constructor

So, does C++ encourage us to initialize all the data members in the constructor or it is just Eclipse's logic?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    I would call it correct object-oriented practice: Every variable should be initialized and the object ready for use. "No meaning"? Then initializing it to 0, -1, or MIN_INTEGER won't be harmful. – duffymo Oct 14 '15 at 11:56
  • Exactly @duffymo. I am just curious if there is something in the standard that urges me to do so. – gsamaras Oct 14 '15 at 11:56
  • 6
    Using the value of an uninitialised variable is undefined behaviour. The safest approach is to initialise every variable at the point of construction. For class members, your constructors should ensure that every variable is initialised or that it has a default constructor of its own that does the same. – Andrew Oct 14 '15 at 11:57
  • 2
    @duffymo I thought in OO (not that anything in the question talks about OO) it shouldn't matter what a private member is set to. It is up to the class to maintain whatever invariants need to be maintained. – juanchopanza Oct 14 '15 at 11:57
  • Show a real example. As written, you could delete both private members, since they are not observable. – Kerrek SB Oct 14 '15 at 11:57
  • The code wouldn't compile anyway, so no problem. – juanchopanza Oct 14 '15 at 11:58
  • @juanchopanza that's what I thought! That's why I am asking, in order to know what C++ standard says about it. Kerrek, I do not have any, I just started a new C++ project and this came up! Andrew the class knows about the fact and won't use the uninitialized variable (however in a big project your comment would be very good). – gsamaras Oct 14 '15 at 12:08
  • 2
    The standard doesn't say anything about it explicitly. But reading from an uninitialized variable is UB. – juanchopanza Oct 14 '15 at 12:09
  • Of course @juanchopanza, I am asking for what the standard says, not for what will happen if I read that data member. So, an answer that says that standard allows you to leave the data member uninitialized would be accepted. – gsamaras Oct 14 '15 at 12:11
  • BTW, warnings are not errors. Compiler help you to point potential errors. – Jarod42 Oct 14 '15 at 12:17
  • Correct @Jarod42, but still I am worrying about warnings as much as I worry about errors! – gsamaras Oct 14 '15 at 12:18
  • @gsamaras If the standard didn't allow it, it would be an error, not a warning. You're allowed to leave everything except reference variables uninitialised. The reason for the warning is that this is usually a very bad idea. – molbdnilo Oct 14 '15 at 12:23
  • OK @molbdnilo, thank you! – gsamaras Oct 14 '15 at 12:24
  • In general, the data members compose object's state. In combinatorial terms all possible initial state should be defined. That is the reason why I think it would make sense to assure that all member is initialized. – lrleon Oct 14 '15 at 12:38
  • Thank you @lrleon, I will agree. – gsamaras Oct 14 '15 at 12:42

5 Answers5

19

Should constructor initialize all the data members of the class?

That would be a good practice.

So, does C++ encourage us to initialize all the data members in the constructor?

It's not required by the c++ standard. As long as you initialize all variables before they're used, your program is correct in that regard.

or it is just Eclipse's logic?

Quite likely. Neither g++ nor clang versions that I tested warn about this when all warnings are enabled. The logic may or might not be based on high integrity c++ coding standard 12.4.2 or some other coding standard or style guide.

eerorika
  • 232,697
  • 12
  • 197
  • 326
8

C++ doesn't require attributes to be initialized in constructor, except in case of const attributes where there value must be defined in initialization list.

However, it is clearly a good practice to initialize every attributes in constructor. I cannot count how many bugs I've met due to a non initialized variable or attributes.

Finally, every object should permanently be in a consistent state, which include both public (accessible) attributes and private attributes as well. Optimization should not be a reason for keeping an object un-consistent.

toubab
  • 109
  • 6
  • 1
    "I cannot count how many bugs I've met due to a non initialized variable or attributes" - that could have been my own statement ! – Doc Brown Nov 23 '16 at 22:21
7

Fully disagree with all the answers and comments. There is absolutely no need to default initialze a member when it is not needed. This is why C/C++ never initializes built-in types as members or automatic variables - because doing so would impede performance. Of course, it is not a problem when you create your object/variable once (that's why statics are default-initialized), but for something happening in a tight loop default initialization might eat valuable nanoseconds.

The one exception to this rule would, in my view, be pointers (if you happen to have raw pointers in your code). Raw pointers should be NULL-initialized, since having invalid pointer is a direct way to undefined behaviour.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • Nice approach and +1 for being proud to go towards the current. – gsamaras Oct 14 '15 at 13:03
  • "This is why C/C++ never initializes built-in types as members or automatic variables" is this fact or opinion? Unfortunately this answer sounds like early optimization. For the sake of a single machine instruction, you require every future reader of the code to verify you were correct in leaving it out. At a minimum I would expect a reasonable comment next to something that causes a potential programming problem warning from my analysis tools. With that in mind I have downvoted. – Jonah Graham Oct 14 '15 at 13:44
  • @JonahGraham, can you elaborate? I am not sure what you are criticizing. Are you conetending the fact that C/C++ do not default initialize automatic variables? Or are you contentind the suggested reason for this? – SergeyA Oct 14 '15 at 13:51
  • I understand. But in those cases where I require a certain structured and contiguous memory layout I would use C style and I would deal the situation with `struct`. If one deals with object orientation, then I believe is better to initialize all the members – lrleon Oct 14 '15 at 14:03
  • @lrleon, not sure what you mean by saying 'deal with situation with struct' – SergeyA Oct 14 '15 at 14:25
  • The class concept is OO. In this sense, the object state is represented through its data members, which should be initialized for assuring an initial consistent object state, what one would say that in OO is very convenient; in order to debugging, by example. But sometimes one does not want OO, but a structured and contiguous memory layout; for examples, a network packet or a file chunk; in both cases one is interested in a structured layout. In these cases, one can use `struct` (as convention) and not necessarily one is obliged to initialize the fields, since one is not thinking in OO. – lrleon Oct 14 '15 at 15:27
  • @SergeyA I am contesting that "this is why" part of your statement, not the fact that it does or doesn't happen, but that it does or doesn't happen for speed performance reasons (as opposed to other reasons). i.e. your statement implies that the part of the C/C++ specs that deal with init of auto variables was a decision itself, rather than enshrining actual behaviour of existing compilers. – Jonah Graham Oct 14 '15 at 15:38
  • @SergeyA furthermore even if a variable in a loop was default initialize, an optimizing compiler (aka a modern compiler) would probably optimize out the initialization if it was not needed. i.e. like in this code for `var`: for (i = 0; i < N; i++) { int var; // theoretically default initialized to zero // some other code that does not mention var var = a + b; } the (theoretical) `var = 0` would be optimized out. Just as if you had typed `int var = 0;`. – Jonah Graham Oct 14 '15 at 15:46
  • Turns out I don't know how to put code snippet in comments. Anyway, I would be happy to explain my reasons for the downvoting, upvote it if the answer is updated to provide evidence of the "why". – Jonah Graham Oct 14 '15 at 15:48
  • @JonahGraham, I am not on friendly terms with Bjarne Strousstrouppe, so I can not ask him the 'why' question. I know a guy who is, but I will not bother him with this either. So of course, my 'why' is a speculation. Nevertheless, the idea that it was done out of efficiency not only seems quite plausible, it is also considered to be common knowledge. For instance, see http://stackoverflow.com/questions/2091499/why-global-and-static-variables-are-initialized-to-their-default-values. I will not beg for upvote, though. – SergeyA Oct 14 '15 at 17:54
  • 6
    @SergeyA, And what makes pointers different than other types? Uninitialized data is Undefined Behaviour. Here and There. C++ allows you to uninitialize a variable for efficiency reasons, this doesn't mean we have to uninitialize things or they will run slower. Initialization is a neccesarry task, and must be done before using the values stored (stored means initialize) or you'll get rubish. If you think an integer is not as important as a pointer, just use it as the index to an array and you'll have a covered pointer. And c++ doesn't check for array bounds also. – Luis Colorado Oct 15 '15 at 06:19
  • 1
    By the way, Initialization is so important that deserves the invention of the constructor to do this, so you never forget to do it. – Luis Colorado Oct 15 '15 at 06:23
  • 1
    @LuisColorado, you are simply wrong. Unitialized values generally ARE NOT undefined behaviour on their own - the value put inside them is undefined, but you can use them normally. Invalid pointer, on the other hand, is - you can't use it in any way. – SergeyA Oct 15 '15 at 13:22
  • 2
    *"There is absolutely no need to default initialize a member when it is not needed. "* - making it more unlikely to create a program which sometimes masks a bug and sometimes don't is a very good reason in my eyes to initialize any member by default, and only save that initialization if that kind of optimization gives a relevant performance benefit. – Doc Brown Nov 23 '16 at 22:18
5

For completeness, the warning comes from the C/C++ Code Analysis. In particular the problem is Potential Programming Problems / Class members should be properly initialized

To change the code analysis settings (in this case I recommend per-project) edit the project properties. You can disable the whole warning, or disable it on just the files that violate the warning condition.

show the warning

As for comparing CDT with GCC or CLang, this appears to be a case where additional code analysis is being done by CDT compared to what is available from the compilers. Of course that is to be expected as the CDT Code Analysis' remit is greater than that of the compiler.

PS, If you are up for it, you can read the implementation of this particular checker.

Jonah Graham
  • 7,890
  • 23
  • 55
  • Very good, if you had answered first, I would accept..I will upvote another answer of yours I like, to be fair! :) – gsamaras Oct 14 '15 at 13:48
0

As it has been already said, you should always initialize pointers and of course const objects are mandatory.

In my opinion you should not initialize when it is not necessary but it is good to check for all non constructor initialized variables once in a while because they are source of very frequent and hard to find bugs.

I run Cppcheck every few months. This gives me more than one hundred 'false' warnings like "Member variable 'foo::bar' is not initialized in the constructor." but once in a while it discovers some real bugs so it is totally worth it.

rockefelox
  • 61
  • 1
  • 3