Skip to content

CWG2938 [basic.link] Inheriting linkage from previous declaration #609

@Endilll

Description

@Endilll

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

Reference (section label): [basic.link]

Link to Mattermost thread: https://chat.isocpp.org/general/pl/7tdru1ma9fgrddm8h4tjozwwca

Issue description

Consider the following excerpt from https://eel.is/c++draft/basic.link#example-1 (numbering is mine):

static void f(); // #1
void q() {
  extern void f(); // #2, internal linkage
}

#1 has internal linkage without any doubt per [basic.link]/3.1.

Then we put #2 through [basic.link], and I think the following happens:

  1. #2 belongs to a namespace scope per [dcl.meaning]/3.5 and [basic.scope]/2.
  2. 3.1 doesn't apply, because #2 is not explicitly declared static.
  3. 3.2 and 3.3 don't apply to function declarations.
  4. Then we move to p4.
  5. #2 has not been given internal linkage "above" (which presumably is referring to p3).
  6. #2 is a function declaration, so p4 applies per [basic.link]/4.2.
  7. Friend declarations are not involved, so we skip over 4.7 and 4.8.
  8. Enclosing namespace is global, so it has external linkage, which means 4.9 also doesn't apply.
  9. Modules are not involved, so 4.10 doesn't apply either.
  10. [basic.link]/4.11 makes #2 to have external linkage.

[basic.link]/8 establishes that #1 and #2 declare the same entity, then [dcl.stc]/6 makes the example ill-formed.

That said, http://eel.is/c++draft/basic.link#example-1, https://eel.is/c++draft/dcl.stc#note-4, and https://eel.is/c++draft/dcl.stc#example-1 all imply that there's an interpretation of the wording that makes later declarations "inherit" linkage from the previous declaration, but I fail to read the wording this way. One could argue that linkage is a property of an entity, so "inheritance" could work automatically after doing declaration matching, but [basic.link]/2 explicitly says that linkage is a property of a name, and not of an entity being declared. Moreover, [basic.link]/8 requires linkage of both declarations to be known prior to declaration matching.

Note that language linkage has explicit wording for this in [dcl.link]/6. Prior to P1787R6, we had wording of a similar effect in [basic.link]/6 (emphasis mine):

If there is a visible declaration of an entity with linkage, ignoring entities declared outside the innermost enclosing namespace scope, such that the block scope declaration would be a (possibly ill-formed) redeclaration if the two declarations appeared in the same declarative region, the block scope declaration declares that same entity and receives the linkage of the previous declaration.

Could I get a clarification how the current wording supports aforementioned examples and notes, if they are correct?

This was discussed with Davis on Mattermost: https://chat.isocpp.org/general/pl/7tdru1ma9fgrddm8h4tjozwwca

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