> On May 12, 2016, at 2:47 PM, Richard Smith <[email protected]> wrote:
> On 12 May 2016 at 13:34, John McCall <[email protected] 
> <mailto:[email protected]>> wrote:
>> On May 12, 2016, at 12:07 PM, Richard Smith <[email protected] 
>> <mailto:[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. :)
> 
> C++ truly is a remarkable language.
>  
> 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.
> 
> The new semantic model fixes a whole laundry list of issues caused by 
> building separate declarations for them -- we want to access-check the 
> constructor as if it were in the base class, we want to handle default 
> arguments as we would for the base class overload set, we want failures in 
> the delegating call in the inheriting constructor count as "immediate 
> context" for the purposes of SFINAE, and so on (see wg21.link/cwg1573, 
> wg21.link/cwg1645, wg21.link/cwg1715, wg21.link/cwg1736, wg21.link/cwg1941, 
> wg21.link/cwg1991). Synthesizing a constructor / constructor template makes 
> it hard to get these cases right, as well as giving the wrong semantics for 
> argument passing.

Alright, I accept that we should mangle these differently, and 'CI' <variant> 
<type> seems reasonable.

John.
_______________________________________________
cxx-abi-dev mailing list
[email protected]
http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev

Reply via email to