0

Teaching myself C++ and working on an example from a book I picked up at the local Barnes and Noble. "Professional C++ by Marc Greggoire". I didn't realize that this book was meant for someone with a little more experience than myself but I've been muddling through it with the help of online tutorials and of course SO.

The example is an Employee class that has two constructors. One explicitly defaulted and the other intitializing private members with references.

Using Code Blocks IDE this code:

#include <iostream>
#include <string>
using namespace std;

class Employee
{
public:

    Employee() = default;                           //default constructor
    Employee(const std::string& firstName,
             const std:: string& lastName);

private:
    std::string mFirstName;
    std::string mLastName;
};

Employee::Employee(const string& firstName, const string& lastName) : mFirstName(firstName), mLastName(lastName)
{
}

int main()
{
    cout << "Testing the Employee class." << endl;

    Employee emp;

    return 0;
}

generates a compiler warning on the explicitly defaulted constructor that the variables should be initialized in a member initialization list [-Werror=effc].

Quick search of SO shows that maybe this can be ignored.

Can I ignore the gcc warning: ‘Foo::m_bar’ should be initialized in the member initialization list [-Weffc++]

Since I'm not quite understanding why this is ok to ignore, I tried anyway to get the warning to go away by providing a member initialization in a definition for the default constructor:

Employee::Employee() : mFirstName("Empty"), mLastName("Empty")
{
}

only to find that an error has now been generated by the compiler about the explicitly defaulted constructor, "error: definition of explicitly-defaulted 'Employee::Employee()' and the previous warning remaining. Another SO search gave me this:

How is "=default" different from "{}" for default constructor and destructor?

It seems to indicate that using Employee() = default; would be more clear but using Employee(); will still work. So I kept the default constructor initialization and changed the default constructor declaration from:

Employee() = default;

to

Employee();

Now the compiler is happy with the new default constructor declaration with member initialization list but I'd really like to understand what is going on here. I understand completely why (from the SO discussions) the compiler errors if there is an explicitly defaulted constructor yet a user provides an initialization list. This makes sense. What doesn't make sense to me is why the compiler is asking for one when clearly, providing one with an explicitly defaulted constructed is contradictory.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Dan
  • 758
  • 6
  • 20
  • 1
    You may ignore the warning. The data members having the type std::string of the class will be default-initialized. – Vlad from Moscow Oct 02 '19 at 14:30
  • 1
    This warning is just badly implemented in my opinion. The whole point of `= default`ing constructors is to rely on the default constructors of all members (and base classes). The warning has a purpose when some members are unmentioned in a member initializer list ("did you forget to initialize them?") but there is nothing gained from the compiler coughing up a warning where you are already explicitly stating your intent ("default everything"). – Max Langhof Oct 02 '19 at 14:50
  • Exactly what I was thinking Max but wasn't comprehending that people much more versed in this than I could do something so silly. I appreciate all the responses greatly! – Dan Oct 02 '19 at 15:07

1 Answers1

1

As the linked post says, that warning is a bug in your compiler.

The code was fine, and the initialisation was fine. The defaulted default constructor (!) will default-construct the string members too.

Your attempt to workaround the warning in another way involved creating your own default constructor, even though you've declared it as defaulted. That's like getting in and driving an automatic car, then opening the bonnet en route and trying to change gear yourself.

Removing default then makes it just a normal, user-declared default constructor and everything's fine again… if more verbose than it needed to be.

(The re-use of the word "default" is a really unfortunate choice by the committee!)

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Thank you! I did not see the part about it being a bug in my compiler. In my defense it was about the 1000th page I had visited to try and figure it out but much appreciate the feedback none the less as I was beginning to go a little crazy. I wonder if there will be updates for the compiler to fix this. – Dan Oct 02 '19 at 14:51