> 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

Reply via email to