Reputation: 435
The standard [basic.link#2.4] states:
When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.
According to cppreference:
Member functions of a local class have no linkage.
I haven't been able to find anything in the standard to confirm this, though.
Now consider the following example:
auto make_local() {
struct Local {
void member() {}
};
return Local{};
}
int main() {
auto local = make_local();
local.member(); // Ok
}
This code compiles, even though the name Local::member
is referred to in a different scope than it is declared in.
Since this is not what I expected, my understanding of linkage is incorrect. Therefore, my question is - what does it actually mean for an entity to have no linkage?
Upvotes: 2
Views: 144
Reputation: 490158
Linkage refers to the implementation looking at two instances of the same name, and linking them together, so they refer to the same underlying object.
For example, if I have one file (well, translation unit, really, but I'm going to call that a "file" for convenience) containing (outside any function):
int a = 1;
and another file that contains:
extern int a;
The implementation will look at those, and link them together--that is, decide that a
at namespace scope in both files refers to the same actual object.
By contrast, if I have something like:
static int a = 1;
...in one file, and:
static int a;
...in another file, the fact that they're both marked static
means they have internal linkage. That means other references to a
inside the same file can refer to that file's a
, but each file has its own copy of a
separate from any other file.
A name with no linkage means that some other use of the same name won't automatically refer to the same object.
Linkage is really about names and the implementation matching names to see whether two uses of the same name refer to the same objects, or different objects.
In your case, you're not trying to use the same name in two different places, and expecting the compiler to figure out that both those uses of the same name refer to the same object. Instead, you're getting the address of the object, then returning that address to be used from somewhere else. That's perfectly fine as long as the object whose address you got has lifetime extending throughout the time you use it.
Upvotes: 1
Reputation: 170084
We must keep in mind the leading sentence of paragraph 2 when interpreting "referred to" here.
A name is said to have linkage when it can denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope
This is about linking declarations that ultimately refer to the same entity under the one-definition rule, and not about whether we can use a name in an expression. local.member()
is not a declaration, and so doesn't contradict the above paragraph.
And indeed, there is no way to write another declaration that that will refer to make_local::Local::member
. Its lack of linkage is upheld, since if we introduce another local class in another function:
auto make_local() {
struct Local {
void member() {}
};
return Local{};
}
auto make_another_local() {
struct Local {
void member() {}
};
return Local{};
}
int main() {
auto local = make_local();
local.member(); // Ok
auto local2 = make_another_local();
local2.member();
}
We will end up with a completely new class and member function, not at all linked to the previous one. This is in contrast to declarations with internal linkage, which must all (and there can be more than one) refer to the same entity in the translation unit they appear in.
Upvotes: 2