2

In the following example, struct A does not have default constructor. So both struct B and struct C inherited from it cannot get compiler-generated default constructor:

struct A {
    A(int) {}
};

struct B : A {
    B() = default; //#1
};

struct C : A {
    C();
};

C::C() = default; //#2

#1. In struct B, defaulted default constructor is declared inside the class, and all compilers accept it, with only Clang showing a warning saying that explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]

#2. But defaulted default constructor declared outside of struct C generates a compiler error. Demo: https://gcc.godbolt.org/z/3EGc4rTqE

Why does it matter where the constructor is defaulted: inside or outside the class?

user438383
  • 5,716
  • 8
  • 28
  • 43
Fedor
  • 17,146
  • 13
  • 40
  • 131
  • 1
    Because that's how the syntax is defined in the standard – pm100 Apr 22 '22 at 13:42
  • *Why does it matter where the constructor is defaulted: inside or outside the class?* -- Maybe the simple answer is "those are the current rules of C++"? If you have a line or paragraph in the standard that allows your code to compile, but it doesn't compile for those compilers you tested for, you could state it. – PaulMcKenzie Apr 22 '22 at 13:42
  • @PaulMcKenzie cop-out answer. *Why are those the current rules of C++?* – user253751 Apr 22 '22 at 14:10
  • @user253751 Follow-up. Go ask the committee. Or suggest it to them and see what happens. No different than asking "why static initializers are not allowed in classes" back in the C++98 days. – PaulMcKenzie Apr 22 '22 at 14:11
  • @PaulMcKenzie Many questions about the C++ language design have reasonable answers. Like Alan's answer to this question. – user253751 Apr 22 '22 at 15:35
  • @user253751 Then does this all become opinion-based? – PaulMcKenzie Apr 22 '22 at 16:33
  • @PaulMcKenzie only in your mind and nobody else's. "Why can't I dereference an uninitialized pointer?" "Because the standard says so." – user253751 Apr 22 '22 at 16:34
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244111/discussion-between-paulmckenzie-and-user253751). – PaulMcKenzie Apr 22 '22 at 16:40

1 Answers1

5

Note that if you actually try and instantiate B then you'll also get the error that B::B() is deleted: https://gcc.godbolt.org/z/jdKzv7zvd

The reason for the difference is probably that when you declare the C constructor, the users of C (assuming the definition is in another translation unit) have no way of knowing that the constructor is in fact deleted. At best this would lead to some confusing linker error, at worst it'd just crash at runtime. In the case of B all users of B will immediately be able to tell that the default constructor is deleted so it does no harm (even if it makes no sense as warned by clang) to declare it as defaulted.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60