8

In such a situation

namespace n {
    void f() {
        void another_function();
    }
}

Should the function another_function be defined inside the namespace n or outside? VS 2012 (with the November CTP) says it should be outside, and GCC 4.7.2 on the Mac says it should be inside. If I do the wrong one, I get undefined symbol errors from the linkers.

I generally trust GCC to be more compliant to the standard, but this is C++ and you can never be sure.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • Why do you want to do that? – Billy ONeal Jan 03 '13 at 18:34
  • 1
    @BillyONeal because `another_function` is an implementation detail and `f` is a template. – Seth Carnegie Jan 03 '13 at 18:34
  • 1
    But declaring `another_function` inside `f` doesn't make it less visible than `f`. It will just cause multiple definition errors if someone happens to define their own `n::another_function`. – Billy ONeal Jan 03 '13 at 18:40
  • @BillyONeal no client will/should be putting things into my namespace since it's a library. It does make it slightly less visible since they have to work to get the prototype. Is there a better way to do it? – Seth Carnegie Jan 03 '13 at 18:42
  • 1
    I would just put the prototype inside `your_namespace::detail`. That's what boost does in these situations anyway. The convention is that anything inside a namespace `detail` are implementation details. – Billy ONeal Jan 03 '13 at 18:43

2 Answers2

13

C++11 3.5 (as well as C++03)

7 When a block scope declaration of an entity with linkage is not found to refer to some other declaration, then that entity is a member of the innermost enclosing namespace. However such a declaration does not introduce the member name in its namespace scope.

The declaration in your example declares n::another_function.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
3

According to N3485 7.3.1 [namespace.def]/6, the correct answer is n::another_function.

The enclosing namespaces of a declaration are those namespaces in which the declaration lexically appears, except for a redeclaration of a namespace member outside its original namespace (e.g., a definition as specified in 7.3.1.2). Such a redeclaration has the same enclosing namespaces as the original declaration. [ Example:

namespace Q {
    namespace V {
        void f(); // enclosing namespaces are the global namespace, Q, and Q::V
        class C { void m(); };
    }
    void V::f() { // enclosing namespaces are the global namespace, Q, and Q::V
        extern void h(); // ... so this declares Q::V::h
    }
    void V::C::m() { // enclosing namespaces are the global namespace, Q, and Q::V
    }
}

—end example ]

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552