17

In C++, putting a function or a variable in an anonymous namespace makes its linkage internal, i. e. the same as declaring it static on a file-level, but idiomatic C++.

What about an anonymous namespace within a normal namespace? Does it still guarantee internal linkage?

// foo.cpp

void func1() {
    // external linkage
}

static void func2() {
    // internal linkage
}

namespace {
    void func3() {
        // internal linkage
    }
}

namespace ns1 {
    void func4() {
        // external linkage
    }

    namespace {
        void func3() {
            // still internal linkage?
        }
    }
}
Chubsdad
  • 24,777
  • 4
  • 73
  • 129
Alex B
  • 82,554
  • 44
  • 203
  • 280
  • 1
    Wrong assumption. Variables inside an anonyomus namespace have external linkage, unless declared `static`. – MSalters Nov 15 '10 at 10:12
  • 1
    @MSalters: I think with C++11 this has changed. `§3.5/4: An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage.` – legends2k Oct 21 '13 at 18:09
  • 1
    @legends2k: That's part of another change, which made those names valid as template arguments (In C++03, template arguments needed external linkage, which was satisfied by constants defined in an anonymous namespace) – MSalters Oct 21 '13 at 18:37

3 Answers3

15

C++11 (draft N3337) §3.5/4: (emphasis mine)

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not been given internal linkage above has the same linkage as the enclosing namespace if it is the name of

— a variable; or

— a function; or

— a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3); or

— a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes (7.1.3); or

— an enumerator belonging to an enumeration with linkage; or

— a template.

This guarentees that any unnamed namespace has internal linkage.

What about an anonymous namespace within a normal namespace? Does it still guarantee internal linkage?

Although within a named (normal) namespace, it's an unnamed (anonymous) namespace and thus is guaranteed to have internal linkage as per the C++11 standard.


putting a function or a variable in an anonymous namespace makes its linkage internal, i. e. the same as declaring it static on a file-level, but idiomatic C++.

In C++11 the usage of static in this context was undeprecated; although unnamed namespace is a superior alternative to static, there're instances where it fails which is remedied by static; inline namespace was introduced in C++11 to address this.

Community
  • 1
  • 1
legends2k
  • 31,634
  • 25
  • 118
  • 222
15

It's not necessarily the case that entities in an anonymous namespace have internal linkage; they may actually have external linkage.

Since the unnamed namespace has a name that is unique to the translation unit in which it was compiled, you just can't refer to the entities declared in it from outside of that translation unit, regardless of what their linkage is.

The C++ standard says (C++03 7.3.1.1/note 82):

Although entities in an unnamed namespace might have external linkage, they are effectively qualified by a name unique to their translation unit and therefore can never be seen from any other translation unit.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 2
    A quick follow-up: Do you know if having internal linkage somehow help a compiler make better code transformation decisions for its optimizations, or is it a non-issue? – Alex B Nov 15 '10 at 03:06
  • @Alex B: That's a good question. My guess would be that if a compiler or linker can perform optimizations on entities with internal linkage, they could perform the same optimizations on entities in an unnamed namespace. I can't say for sure, though. Others here would know much better than I do. – James McNellis Nov 15 '10 at 03:11
5

$3.5/3 - "A name having namespace scope (3.3.6) has internal linkage if it is the name of

— a variable, function or function template that is explicitly declared static; or,

— a variable that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; or

— a data member of an anonymous union.

So, I doubt if any of the names 'func3' and 'func4' in your program have internal linkage at all. They have external linkage. However, it is just that they can not be referred from other translation units in accordance with the quote from James.

Chubsdad
  • 24,777
  • 4
  • 73
  • 129