-2

My question is very similar with What does "internal linkage" mean?. But I still feel confused so I have to ask.

C++11 ISO says:

A name having namespace scope has internal linkage if it is the name of a variable, function or function template that is explicitly declared static; or ...

When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.

However, in the following code:

namespace N {
  static int t = 3;
}

int main() {
  int p = t + 1; // complain here: t is undefined
  return 0;
}

Why is it like that? I mean main function and declaration of namespace N are in the same source file so they are in the same translation unit, right? And t has namespace scope and explicitly declared static. So why t is still not found?

Community
  • 1
  • 1
  • 1
    You have to qualify the namespace using `N::`, that's all of it's purpose. – πάντα ῥεῖ Sep 30 '18 at 17:51
  • Surely, I know that. But I hope to know the reason, Could you point out why it happens? I mean, without specifying namespace, then declaration of namespace N and main function are not in the same translation unit? – cyanbuckeye Sep 30 '18 at 17:56
  • I don't understand what you're asking. Your code doesn't work because `t` is in `namespace N`, so you need to write `N::t` to access it. That's the whole point of namespaces. – melpomene Sep 30 '18 at 18:06

1 Answers1

2

You're mixing two separate concepts: scope and linkage.

Scope tells you where a name is visible. Namespace scope means that the name is visible in the namespace where it's defined. Outside of that namespace, the name is not visible. That's why you have to say N::i in code that's not inside the namespace N.

Linkage is about objects being available in other translation units. Forget the namespace for a moment; static int i = 3; would create an object of type int named i with the initial value 3. Because it's marked static it has internal linkage. That object can be used in the translation unit (loosely, the same source file) where its defined. It cannot be used in any other translation unit. So if another source file said extern int i; and tried to do something with i it wouldn't link: undefined symbol i.

The quoted text talks about the intersection of these two: static objects defined inside namespaces. It's a little fuzzy, but should be clearer if you read it as "it ... can only be referred to by names from other scopes in the same translation unit." Or "it ... cannot be referred to by names in any other translation unit." That is, it limits how the name can be used. It does not expand the scope of the name; it's still in namespace scope.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165