Search code examples
c++constructororder-of-executionmember-initializationinitialization-order

Assignment operation in member initializer lists


I have the following Stack class.

class Stack{
public:
    int size;
    int* x;
    Stack() : size(10), x(new int[10]) {}
    Stack(const Stack& s) : x(new int[size=s.size]) {}

};

Notice the assignment in the copy constructor. The code works, compile fine and compiler (gcc) doesn't complain even with -Wall -Wextra flags. Does the compiler automatically rewrite the compiler to this?

Stack(const Stack& s) : size(s.size), x(new int[size]) {}

Or is there some other magic? I noticed when I change the definition order, the compiler complaints about not-in-order initialization. So I assume it's the case I mentioned. I couldn't find anything in the documentation and the ASM output doesn't help me either.


Solution

  • Does the compiler automatically rewrite the compiler to this?

    Stack(const Stack& s) : size(s.size), x(new int[size]) {}
    

    No.

    Stack(const Stack& s) : x(new int[size=s.size]) {}
    

    can be though of as being

    Stack(const Stack& s) : size(), x(new int[size=s.size]) {}
    

    but it isn't really since actually writing size() would value initialize it, meaning it is zero initialized, but since it is the compiler that synthesizes the initialization, default initialization[1] happens meaning it is not initialized. Then you assign a value to it in x's initialization. This is "safe", meaning it works in this case, but I wouldn't recommend it it.

    Stack(const Stack& s) : size(s.size), x(new int[s.size]) {}
    

    initializes both members and if you ever change the order of them in the class, you will still have the correct behavior.