Date: Thu, 22 May 2025 13:33:31 +0200
On 22/05/2025 12.50, Stephan Bergmann via Std-Discussion wrote:
> I wonder what the expectations are when a constructor has an attribute
> (like [[deprecated]]) and is inherited by a derived class---should that
> attribute also be honored by the (implicit) inheriting constructor?
Yes, I think so.
> For
> example, given
>
>> struct B {
>> [[deprecated]] B();
>> [[deprecated]] B(int);
>> [[deprecated]] void f();
>> };
>> struct D: B {
>> using B::B;
>> D(bool);
>> using B::f;
>> void f(bool);
>> };
>> void f() { // Clang GCC MSVC
>> B b1; // + + +
>> B b2{}; // + + +
>> B b3(0); // + + +
>> B b4(0); // + + +
>> D d1; // (+) (+) (-)
>> D d2{}; // - - (-)
>> D d3(0); // - (+) -
>> D d4(0); // - - -
What's the difference between those two?
They seem identical.
>> D d5(false);
>> b1.f(); // + + +
>> b1.f(); // + + +
>> d1.f(); // + + +
>> d1.f(); // + + +
>> d1.f(false);
>> }
>
> various compilers behave differently (Clang 20.1.0, GCC 15.1, MSVC
> 17.13, see <https://gcc.godbolt.org/z/Pbffd3nzP>): While I would
> naively assume that all the lines with a trailing comment would be
> warned about, that appears to hardly be the case for the uses of
> inherited constructors (d1--d4). Clang and GCC somewhat indirectly
> ("<source>:17:7: note: in implicit default constructor for 'D' first
> required here", etc.) warn about only some uses (but do warn about all
> the individual calls to member function f, as would meet my
> expectations). (And MSVC even refuses to compile the declarations d1
> and d2, "'D': no appropriate default constructor available".)
The model for inheriting constructors got reworked a number of years
ago; now there are no synthesized declarations for inherited constructor
in the derived class; instead they directly participate in overload
resolution (and other base classes and data members are default-initialized
as a side effect; see [class.inhctor.init]). Thus, I'd expect all base
class constructor properties to be "active".
The formatting of a warning is quality-of-implementation, of course.
Jens
> I wonder what the expectations are when a constructor has an attribute
> (like [[deprecated]]) and is inherited by a derived class---should that
> attribute also be honored by the (implicit) inheriting constructor?
Yes, I think so.
> For
> example, given
>
>> struct B {
>> [[deprecated]] B();
>> [[deprecated]] B(int);
>> [[deprecated]] void f();
>> };
>> struct D: B {
>> using B::B;
>> D(bool);
>> using B::f;
>> void f(bool);
>> };
>> void f() { // Clang GCC MSVC
>> B b1; // + + +
>> B b2{}; // + + +
>> B b3(0); // + + +
>> B b4(0); // + + +
>> D d1; // (+) (+) (-)
>> D d2{}; // - - (-)
>> D d3(0); // - (+) -
>> D d4(0); // - - -
What's the difference between those two?
They seem identical.
>> D d5(false);
>> b1.f(); // + + +
>> b1.f(); // + + +
>> d1.f(); // + + +
>> d1.f(); // + + +
>> d1.f(false);
>> }
>
> various compilers behave differently (Clang 20.1.0, GCC 15.1, MSVC
> 17.13, see <https://gcc.godbolt.org/z/Pbffd3nzP>): While I would
> naively assume that all the lines with a trailing comment would be
> warned about, that appears to hardly be the case for the uses of
> inherited constructors (d1--d4). Clang and GCC somewhat indirectly
> ("<source>:17:7: note: in implicit default constructor for 'D' first
> required here", etc.) warn about only some uses (but do warn about all
> the individual calls to member function f, as would meet my
> expectations). (And MSVC even refuses to compile the declarations d1
> and d2, "'D': no appropriate default constructor available".)
The model for inheriting constructors got reworked a number of years
ago; now there are no synthesized declarations for inherited constructor
in the derived class; instead they directly participate in overload
resolution (and other base classes and data members are default-initialized
as a side effect; see [class.inhctor.init]). Thus, I'd expect all base
class constructor properties to be "active".
The formatting of a warning is quality-of-implementation, of course.
Jens
Received on 2025-05-22 11:33:38