Why should I initialize member variables in the order in which they are declared?

I wrote the code today and received a strange compilation error that seems to be caused by the initialization of member variables in a different order than they were declared.

Example:

class Test { int a; int b; public: Test() : b(1), a(2) { } }; int main() { Test test; return 0; } 

Then if I compile it with -Werror -Wall :

 $ g++ -Werror -Wall test.cpp test.cpp: In constructor 'Test::Test()': test.cpp:3:9: error: 'Test::b' will be initialized after [-Werror=reorder] test.cpp:2:9: error: 'int Test::a' [-Werror=reorder] test.cpp:6:5: error: when initialized here [-Werror=reorder] cc1plus: all warnings being treated as errors 

I understand that -Wall explicitly asks GCC to jump to the top with warnings, but I assume there is a reason for everyone. So, how can the initialization order of member variables be?

+56
c ++ compiler-warnings g ++
Aug 31 2018-12-21T00:
source share
6 answers

The reason is that they are initialized in the order in which they are declared in your class, and not in the order that you initialize in the constructor, and warn that your constructor order will not be used.

This should help prevent errors when the initialization of b depends on a or vice versa.

The reason for this ordering is that there is only one destructor, and it needs to choose the “reverse order” to destroy the class member. In this case, the easiest solution was to use the declaration order inside the class to make sure that the attributes were always destroyed in the correct reverse order.

+84
Aug 31 2018-12-12T00:
source share
— -

Why should I initialize member variables in the order in which they are declared?

Elements will be initialized in the same order in which they are declared, whether you want it or not. The warning informs you that the order you are requesting is different from the actual initialization order.

+42
Aug 31 '12 at 21:14
source share

You should not, because it reduces readability and is potentially misleading.

If you have done this:

 Test() : b(1), a(b) {} 

it would seem that b and then a were set to 1 , while the actually initialized value of b used to initialize a before b initialized to 1 .

+32
Aug 31 2018-12-12T00:
source share

Actually, the compiler always initializes the variables in the declaration order, even if you write the initializers in a different order. Therefore, if you do not record initializations in the declaration order, the order of your initializers does not correspond to the initialization order, which can lead to subtle errors if the initialization is dependent on each other.

For example, consider the code

 Test(): b(42), a(b) {} 

This is a mistake because a initialized to b , but it looks fine. If you write it in the declaration order (which is the initialization order), the error becomes apparent:

 Test(): a(b), b(42) {} 

Note that the error can also be more subtle than that, for example, to represent a and b types of classes that output something in their constructor; then with the “wrong” order you think that the output of b should appear before a , when in reality the opposite happens. If the output of a , which appears first, leads to an invalid file, which will also lead to an error, but the compiler will not be able to notice the problem if the constructors are in a different translation unit (except that the compiler cannot know if the reordering is not an error ) Therefore, it is reasonable that the compiler simply warns about each instance of an inconsistent order.

+12
Aug 31 '12 at 21:08
source share

I understand that -Wall explicitly asks GCC to go over the top with warnings, but I assume there is a reason for all of them.

-Wall is just the beginning. Contrary to what the name implies, -Wall does not include all warnings. There are some warnings that may be “on top”, but these are precisely the warnings that are not allowed. I always use -Wall plus others.

As for your complaint, as others have already noted, there is a very good reason for this warning. Just because you specify an order does not mean that the compiler will use this order. The order that the compiler should use for the standard is based on a class definition.

+5
Aug 31 '12 at 21:37
source share

An initializer list gives you the flexibility to initialize variables in any order. However, the actual initialization is in accordance with the order in which you declared the class members. To avoid this warning, you should change the initialization / declaration order.

0
Sep 06 '19 at 11:50
source share



All Articles