Search code examples
c++initializationeffective-c++

C++ Explicit declaration triggers a warning in the default constructor


In a Code::Blocks v13.12 project I have a class called Drawable which has a floating point member variable called rotation.

I noticed that explicitly declaring rotation inside Drawable's default constructor would trigger the following warning:

'Drawable::rotation' should be initialized in the member initialization list [-Weffc++]

However, explicitly declaring rotation alongside its definition doesn't do this.

What I want to know is, why does this:

Drawable() {
    rotation = 0.f;
}

Give me a member initialization warning, while this:

class Drawable
{
    ...
    float rotation = 0.f;
    ...
}

And this:

Drawable() : rotation(0.f) {}

Compile without complaint?


Solution

  • The -Weffc++ warning are described as follows:

    Warn about violations of the following style guidelines from Scott Meyers' Effective C++ series of books:

    • Define a copy constructor and an assignment operator for classes with dynamically-allocated memory.
    • Prefer initialization to assignment in constructors.
    • Have operator= return a reference to *this.
    • Don't try to return a reference when you must return an object.
    • Distinguish between prefix and postfix forms of increment and decrement operators.
    • Never overload &&, ||, or ,.

    The warning you are seeing is covered in Item 4: Make sure that objects are initialized before they’re used of Effective C++ 3rd edition which says (paraphrased):

    The rules of C++ stipulate that data members of an object are initialized before the body of a constructor is entered.

    and:

    A better way to write the [...] constructor is to use the member initialization list instead of assignments [...] constructor yields the same end result [...] but it will often be more efficient.

    and (emphasis my wording):

    The assignment-based version first called default constructors to initialize the member variables then promptly assigned new values on top of the default-constructed ones. All the work performed in those default constructions was therefore wasted. The member initialization list approach avoids that problem,

    In C++11 in class member initializers (which also avoids this warning) can simplify initialization if most of your member variables have default values, the one disadvantage is that until C++14 this make your class a non-aggregate.