1

In the current version of the C++ draft (september 2019), paragraph [class.default.ctor]/4 states:

A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) to create an object of its class type ([intro.object]), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration. [...]. Before the defaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and its non-static data members shall have been implicitly defined. [ Note: An implicitly-declared default constructor has an exception specification ([except.spec]). An explicitly-defaulted definition might have an implicit exception specification, see [dcl.fct.def]. — end note ]

[class.dtor]/11 specifies a similar restriction for default destructors.

What does the highlighted sentence mean? Is it a restriction on the program or on the implementation (compiler)?

The first sentence of the quoted paragraph states when a defaulted default constructor is implicitly defined (e.g. when it is odr-used). If the highlighted sentence is a restriction on the program, then the following example should be ill-formed, because at (1) the defaulted default constructor of B is odr-used, therefore it is implicitly defined. However, at this point, the defaulted default constructor of A has not been implicitly defined, therefore the restriction in the highlighted sentence is not respected. This is because I believe that the defaulted default constructor of A is odr-used only after the defaulted default constructor of B is defined. Is this assumption wrong?

struct A {};
struct B : A {};

int main()
{
    B b; // (1)
}

Thank you.

curiousguy
  • 8,038
  • 2
  • 40
  • 58
user42768
  • 1,951
  • 11
  • 22
  • I think the highlighted sentence means, that in your example, the default constructor of A will be implicitly defined **before** the default constructor of B. So it should be a restriction on the compiler. How could you restrict the program on when to implicitly define something? That is the compilers job. – eike Sep 17 '19 at 20:27
  • 5
    I read it as a requirement for the implementation - it should first (implicitly) define the base class constructor, and than the derived one. – SergeyA Sep 17 '19 at 20:27
  • it seems to me that at 1, defaulted default constructor of A is not implicitly defined but default constructor is, e.g. not explicitly defaulted, but implicitly defined default constructor. – Boki Sep 17 '19 at 20:30
  • If the highlighted sentence is a restriction on the implementation then the definition of _implicitly defined_ in the first sentence of the quoted paragraph is not complete. – user42768 Sep 17 '19 at 20:30
  • Why do you think the implicit default constructor of A is not odr-used? – Spencer Sep 17 '19 at 20:35
  • @Spencer If an implicit definition behaves the same as a normal definition, I believe that the implicit default constructor of A is odr-used only in the definition of the implicit default constructor of B. However the highlighted sentence requires A's constructor to be implicitly defined before the implicit definition of B's constructor. – user42768 Sep 17 '19 at 21:18
  • @user42768 And that's why this sentence exists - it tells the implementation to define A::A() before defining B::B(), instead of prematurely defining B::B() and then "undefined reference to A::A()" – L. F. Sep 18 '19 at 10:33
  • @L.F. If this is the case, then the first sentence of [class.default.ctor]/4 enumerates only **some** cases (not all) when the implementation must provide an _implicit definition_. And the highlighted sentence specifies another one. Is this the intention? (I understand that semantically this is the way the paragraph should be interpreted, however I believe that the wording is not completely unambiguous) – user42768 Sep 18 '19 at 11:26
  • @L.F. Also, no matter the order in which the two constructors are defined, there should not be an undefined reference error. – user42768 Sep 18 '19 at 11:55

1 Answers1

0

I agree with the OP that the drafting is sloppy, but I believe that the intent is clear:

  • When the implementation implicitly defines B's default constructor, if A's default constructor hasn't been implicitly defined yet in this translation unit, then the compiler should generate the implicit definition of A's default constructor first.
  • In response to the OP's concern that this creates an additional point where an implicit definition might be generated (besides what is stated in the first sentence of the quoted paragraph), sure, that's one possible way to interpret it. Another way to interpret it is that the compiler starts defining A's default constructor while it's in the middle of defining B's default constructor (because B's default constructor calls A's default constructor "to create an object of its class type", thus requiring A's default constructor to be implicitly defined) and that the former must be completed before the latter. In other words, the first sentence of the quoted paragraph refers to when the generation of the implicit definition begins, and the bolded sentence refers to when it is completed. I think these two interpretations are equivalent, so it's not necessary to choose between them.
Brian Bi
  • 111,498
  • 10
  • 176
  • 312