> On Aug 12, 2016, at 6:06 PM, Richard Smith <[email protected]> wrote:
> On 12 August 2016 at 17:29, John McCall <[email protected] 
> <mailto:[email protected]>> wrote:
> > On Aug 12, 2016, at 4:59 PM, Richard Smith <[email protected] 
> > <mailto:[email protected]>> wrote:
> >
> > C++17 decomposition declarations are (surprisingly) permitted at global 
> > scope. They can't be forward-declared nor made inline (yet...), and it 
> > seems likely that the wording probably didn't *mean* to allow them to be 
> > declared as templates, so we don't appear to need a cross-vendor mangling 
> > for them. However, establishing a convention would be useful for demanglers.
> >
> > For now, I'm mangling global decomposition declarations as:
> >
> >   <unqualified-name> ::= DC <source-name>* E
> >
> > ... where the <source-name>s are the names of the bindings. (I'm mangling 
> > the bindings in the obvious way, as if they were reference declarations, 
> > but they get a mangled name even at global scope.)
> >
> > We could get away with mangling only the name of the first binding, but the 
> > extra information seems useful to people looking at the mangled name.
> >
> > Thoughts? Is it worth specifying this in the ABI?
> 
> For those of us who aren't following the standards process that closely, 
> would you mind explaining the more basic ABI impact of the feature?  Are the 
> individual bindings separate objects that should be mangled as it they were 
> actually declared separately, and so this compound mangling only serves to 
> uniquely identify the initializer in case it contains entities that need / 
> ought to be mangled?
> 
> Yes, but the bindings are always of reference type when they exist at all. In 
> a decomposition declaration like:
> 
>   auto [a, b, c] = expr;
> 
> there are (potentially, see below) four distinct entities: a variable
> 
>   auto e = expr;
> 
> and three bindings (a, b, and c). The mangling above would be used for the 
> 'e' variable. There is no way to reference that implicit variable except 
> through the bindings.

Ah, so it's not like you can declare a bunch of separate extern variables and 
then define them using a single decomposition binding; it really is a sort of 
inherently different declaration that just happens to create multiple names.

> There are two different cases for the behavior of the bindings: either they 
> are built-in bindings representing some subobject of e (including bitfield 
> members)

What.

I mean, okay, it's not actually unreasonable for the language to start taking 
advantage of the nature of reference-binding to do things like this, but it is 
surprising to sneak it in this way.  Have they lifted the restrictions on local 
reference-binding as well?  Obviously they can't be lifted for parameter 
binding, but there's no reason you couldn't bind a local reference to a 
bit-field; it's just implementation complexity.

> with no corresponding entity, or (for types like std::tuple) they act as 
> variables of reference type initialized by some user-specified expression 
> which can have arbitrary side-effects (the corresponding extension mechanism 
> involves specializing standard-library templates and providing a function 
> template to be found by ADL, and has no ABI impact).
> 
> For the built-in case, it seems most straightforward to not generate globals 
> at all (and emit references to a, b, and c directly as references to the 
> corresponding subobject of e),

This is essentially required to handle bit-fields, at least.

The value being decomposed by a builtin binding has to be a pr-value, right?  
Or gets coerced to one?  Or is the model really just as simple as "there's an 
object initialized by this expression, and these names are bound to sub-objects 
of it".

> but for the user-defined extension case, code is run to initialize the 
> bindings and they generally need to act like global variables. A pedantic 
> reading of the standard suggests that you could do this:
> 
>   auto [a] = std::tuple<int>(0); // tu1.cc
> 
>   extern int &&a; // tu2.cc
> 
> ... which would certainly restrict the ABI choices, but I don't think that 
> was an intended consequence of the rules.

If this is formally allowed, I don't see why

  extern int &&a, &&b;
  auto [a,b] = std::make_pair(1,2);

wouldn't be.  But of course this cannot be made to support bit-field references 
without breaking ABI.

> There is (currently) no way to declare the same decomposition declaration 
> across multiple translation units (there's a syntactic limitation preventing 
> them from being static locals, inline globals, or static data members), so in 
> that sense there is no formal ABI impact.

Ok.

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

Reply via email to