Skip to content

[basic.link] It is unclear whether the names of structured bindings has a linkage or not #240

@xmh0511

Description

@xmh0511

Full name of submitter (unless configured in github; will be published with the issue): Jim X

[basic.link] p4 says

The name of an entity that belongs to a namespace scope that has not been given internal linkage above and that is the name of

  • a variable; or
  • a function; or
  • [...]

None of them in the list explicitly mentions structured bindings. Moreover, [basic.pre] p3 says

An entity is a value, object, reference, structured binding...

This implies that structured binding is a separate entity distinguishable from object and reference. This is to say, the structured binding is not a variable because we say

A variable is introduced by the declaration of a reference other than a non-static data member or of an object.
The variable's name, if any, denotes the reference or object.

Consider this example

// TU1
using Arr = int[1];
auto [binding] = Arr{0};

// TU2
using Arr = int[1];
auto [binding] = Arr{0};

Both Clang and GCC agree that the name binding in such two translation units denotes the same entity. See this example.

To determine whether two declarations declare the same entity, [basic.link] p8 applies to it, which says

Two declarations of entities declare the same entity ...

  • they appear in the same translation unit, or
  • they both declare names with module linkage and are attached to the same module, or
  • they both declare names with external linkage.

The only possibility for this case is, the name binding has an external linkage such that two declarations in different translation units declare the same entity. However, as aforementioned, we lack the wording to specify whether the name of structured binding has a linkage or not, it is not clear in the current standard.


Furthermore, in whole [dcl.struct.bind], there is a conflict. In p1, we first say

A structured binding declaration introduces the identifiers v0, v1, v2,… of the identifier-list as names of structured bindings.

Then, in the subsequent paragraph, we instead say

Each vi is the name of an lvalue that refers to...

Note that an lvalue is an expression as said in [basic.lval] p1, why do we say a name of an expression? It seems not to make sense.

Suggested resolution

Given that the implementation's behavior, [basic.link] p4 should explicitly mention structured binding. According to [dcl.struct.bind], a structured binding behaves more like a reference. We may say

Each vi is the name of an lvalue structured binding that refers binds to (What stuff) and whose type is T;

Then, in [expr.prim.id], we can explicitly say what stuff an id-expression designates if it names a structured binding, in the same manner as we have done for reference in [expr.type] p1

The expression designates the object or function denoted by the reference

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions