3

Clang and GCC don't seem to agree about what makes a type default constructible. Is GCC wrong here? Is the formal definition of the standard not clear about this?

#include <concepts>

class base {
protected:
    base() = default;
};

struct der : base {
    using base::base;
    der(int) {}
};

der d; // constexpr base::base() is protected within this context
static_assert(std::semiregular<der>); // fails on GCC

Live example


JHBonarius and alagner have provided the requested information, referring to already existing sources that cover the details pretty well. For now, I think it's best to direct this question more towards Clang's deviating behavior. I've initiated the bug-reporting process and will post any follow ups here.

303
  • 2,417
  • 1
  • 11
  • 25
  • I don't know why it compiles on Clang... bug? It's kind-of weird to me that `using` the base default constructor re-enables the otherwise implicitly deleted default constructor. But if it's correct, it's still protected. – JHBonarius Nov 24 '21 at 12:57
  • @JHBonarius you're basing your statement on the following excerpt from the standard, 10.3.3.2: "if the using-declarator names a constructor, it declares that the class inherits the set of constructor declarations introduced by the using-declarator from the nominated base class.", is that right? – alagner Nov 24 '21 at 13:02
  • @alagner You seem to know where it's in the standard, I don't, but yes. – JHBonarius Nov 24 '21 at 13:06
  • Does this answer your question? [C++ visibility of inherited constructor](https://stackoverflow.com/questions/57695057/c-visibility-of-inherited-constructor) – alagner Nov 24 '21 at 13:34
  • 1
    Does this answer your question? [C++11 inheriting constructors and access modifiers](https://stackoverflow.com/questions/21015909/c11-inheriting-constructors-and-access-modifiers) – JHBonarius Nov 24 '21 at 15:01
  • 1
    based on the dupe, it's a Clang bug... you can report it. Although I don't know exactly where and if there is any chance they will consider it. – JHBonarius Nov 24 '21 at 15:04
  • Thank for providing the information that explains the observed behavior from this question. Let's find out if Clang acknowledges this defect or if they see things differently. – 303 Nov 24 '21 at 23:46

1 Answers1

3

As we discussed in the comments, seems GCC implements the standard right (though it seems counterintuitive):

C++ standard, 10.3.3.2

Each using-declarator in a using-declaration introduces a set of declarations into the declarative region in which the using-declaration appears. The set of declarations introduced by the using-declarator is found by performing qualified name lookup (6.4.3, 13.2) for the name in the using-declarator, excluding functions that are hidden as described below. If the using-declarator does not name a constructor, the unqualified-id is declared in the declarative region in which the using-declaration appears as a synonym for each declaration introduced by the using-declarator. [ Note: Only the specified name is so declared; specifying an enumeration name in a using-declaration does not declare its enumerators in the using-declaration’s declarative region. — end note ] If the using-declarator names a constructor, it declares that the class inherits the set of constructor declarations introduced by the using-declarator from the nominated base class.

Note that factory method works as expected.

EDIT: and it's been already asked and answered ;)

alagner
  • 3,448
  • 1
  • 13
  • 25