c++namespaceslanguage-lawyerlinkageunnamed-namespace

Do entities within an unnamed namespace nested in a regular namespace have internal linkage?


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

What about an unnamed 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?
        }
    }
}

Solution

  • 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.