Repository navigation
CWG2938 [basic.link] Inheriting linkage from previous declaration #609
Description
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:
#2belongs to a namespace scope per [dcl.meaning]/3.5 and [basic.scope]/2.- 3.1 doesn't apply, because
#2is not explicitly declaredstatic. - 3.2 and 3.3 don't apply to function declarations.
- Then we move to p4.
#2has not been given internal linkage "above" (which presumably is referring to p3).#2is a function declaration, so p4 applies per [basic.link]/4.2.- Friend declarations are not involved, so we skip over 4.7 and 4.8.
- Enclosing namespace is global, so it has external linkage, which means 4.9 also doesn't apply.
- Modules are not involved, so 4.10 doesn't apply either.
- [basic.link]/4.11 makes
#2to 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
Activity
AaronBallman commentedon Sep 12, 2024
I think the wording could perhaps be made more clear, but I think the way this works is off an undocumented idea of "name matching" which is slightly different from lookup in that it's actually straightforward (there either is a name already bound to a namespace scope or there is not). I think the way this is supposed to work is:
That said, it's unclear because there's only one name but there are multiple entities involved. So it's easy to get confused by which entity we mean when we say "the name of an entity that belongs to namespace scope". If I'm correct about the whole "name matching" business, maybe that could be made more clear too.
Also, I could be entirely off-base. :-)
jensmaurer commentedon Oct 2, 2024
CWG2938
[-][basic.link] Inheriting linkage from previous declaration[/-][+]CWG2938 [basic.link] Inheriting linkage from previous declaration[/+]