> On May 12, 2016, at 12:07 PM, Richard Smith <[email protected]> wrote:
> On 12 May 2016 at 11:45, John McCall <[email protected]
> <mailto:[email protected]>> wrote:
>> On May 6, 2016, at 2:29 PM, Richard Smith <[email protected]
>> <mailto:[email protected]>> wrote:
>> Per http://wg21.link/p0136r1 <http://wg21.link/p0136r1> an inheriting
>> constructor declaration no longer results in the implicit synthesis of
>> derived class constructors, and instead the behavior of a call to an
>> inherited constructor is that:
>>
>> 1) the portion of a hypothetical defaulted default constructor prior to the
>> base constructor invocation is executed, then
>> 2) the inherited constructor is invoked, then
>> 3) the portion of a hypothetical defaulted default constructor after the
>> base constructor invocation is executed
>>
>> There are a couple of obvious ways we could avoid emitting the code for (1)
>> and (3) in every inherited constructor call site:
>
> This only affects interoperation to the extent that it's done with vague
> linkage, since as far as I know there's no way to give an inherited
> constructor a strong definition.
>
> Yes.
>
> I think we should recommend using (A) in all cases where it's possible, which
> as far as I know is everything except variadic constructors, and then just
> inline all the appropriate initialization for variadics.
>
> OK, sounds fine to me. I don't really think the variadic case will come up
> enough to worry about it. The other benefit of the prefix/suffix functions is
> that we can factor out some of the duplication from the CI functions
> themselves, but that seems very much like a secondary benefit.
I mean, if we wanted to, we could apply that as a code-size optimization across
ordinary constructors when we happen to notice that they have equivalent
initializers.
> (A) has to deal with both constructor variants, though.
>
> Good point. Maybe CI1<type> / CI2<type>?
That makes sense to me if we do need to distinguish inherited constructors.
>
> Is there a reason we can't just continue to mangle the symbol as a C1 or C2
> in the derived class? Just concern about ODR differences when there happens
> to be a non-trivially-copyable type passed by value?
>
> For a C2 constructor that inherits a constructor from a virtual base, the
> signature will be different from the old approach, because parameters will no
> longer be passed at all (whereas before they were passed and discarded).
> That's probably fine for most calling conventions, but seems risky in
> general. [As a further optimization, we could share the same C2 constructor
> for all inherited constructors that inherit from the same (set of) virtual
> base(s), but I'm not sure that's worth putting into the ABI.]
>
> I'm also concerned about there being edge cases where overload resolution
> could pick between constructors from two different base classes despite them
> mangling the same. Highly-contrived example:
>
> constexpr int f(), g();
> struct A { template<int = f()> A(int); };
> struct B { template<int = g()> B(int); };
> struct C : A, B {
> using A::A;
> using B::B;
> };
>
> TU1:
> constexpr int f() { return 0; }
> C c(0);
> constexpr int g() { return 0; }
>
> TU2:
> constexpr int g() { return 0; }
> C c(0);
> constexpr int f() { return 0; }
>
> I think this is valid, with TU1 calling A(int) and TU2 calling B(int).
That is a really amazing example. I feel enriched. :)
I'm surprised that the language model here has changed so much, though. The
inherited constructors really aren't treated as declarations in the derived
class? I would expect it to be a much better language model to treat them as
declarations that just have non-standard semantics when invoked.
John._______________________________________________
cxx-abi-dev mailing list
[email protected]
http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev