9

This question is directly related to this one. Consider the code:

#include <iostream>

inline namespace N1
{
    int x = 42;
}
int x = 10;

int main()
{
    extern int x;
    std::cout << x; // displays 10
}

It displays 10. If I remove the extern int x; declaration then we get an ambiguity compiler time error

error: reference to 'x' is ambiguous

Question: why does the code work with the extern int x declaration work, and why does it stop working when I remove it? Is it because inline namespace variables have internal linkage?

8
  • They don't have internal linkage, unless enclosed by an unnamed namespace. Are you confusing inline and unnamed? Commented Nov 23, 2015 at 18:03
  • @T.C. No, I don't confuse them. I knew that unnamed namespaces have internal linkage. Commented Nov 23, 2015 at 18:05
  • You should probably rephrase the question to "why does it work", since you're probably more interested in that than in the strictly boolean answer to whether inline namespace variables actually have static storage or internal linkage (which is what the current answers address). Commented Nov 23, 2015 at 18:06
  • 2
    OK, now you are confusing static storage duration and internal linkage. Commented Nov 23, 2015 at 18:06
  • This particular lookup is somewhat underspecified. Compare CWG1839. Commented Nov 23, 2015 at 18:13

2 Answers 2

3

No. There is no provision in [basic.link] that would cause x to have internal linkage. Specifically, "All other namespaces have external linkage.", and "other" refers to "not unnamed". Perhaps you were thinking of unnamed namespaces?

Sign up to request clarification or add additional context in comments.

2 Comments

I know thats not specifically what OP asked, but why then does adding extern fix the ambiguity?
@Borgleader: Same reason that extern selects the outermost name in int x; { int x; { int x; { int x; { extern int x; x = 10; } } } }?
1

No, the code works because to avoid breaking existing C code, extern int x; has to work the same way in did in C, in other words creating a local extern to a global namespace (that's all we had in C) variable. Then when you use it later the locally declared extern removes any possible ambiguity.

1 Comment

It refers to the innermost enclosing namespace, not the global namespace. E.g. int x = 10; namespace S { int x = 20; void f() { extern int x; printf("%d\n", x);} } int main() { S::f(); } prints 20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.