I have two source files, a.cpp and b.cpp. In a.cpp, I have a function, foo:
namespace ns { void foo() { std::cout << "foo!"; } }
In b.cpp, I have another function in namespace ns in which I'd like to prototype and call foo:
namespace ns
{
void bar()
{
    void foo();
    foo();       
}
}
While the above is syntactically valid, it leads the compiler to think that foo is in the global namespace (or at least that's what I've deduced from the linker errors I get when I do this). My first two ideas to fix that were void ns::foo(); and namespace ns { void foo(); }, but neither is valid. Is it possible to correctly prototype this function inside bar? 
Note that I know I could simply move this to the file scope or a header file, there have been many questions asked about this, but I want to specifically prototype it inside another function. My compiler is MSVC 14.0 with the latest update.
EDIT: Based on some tests I've done and our discussion in the comments, I believe this is an MSVC bug. Compare:
namespace ns
{
void bar()
{
    void foo();   // link error, MSVC assumes global namespace
    foo();
}
void foo() { }
} // namespace ns
This fails, as stated previously. However, moving the prototype out of the function makes MSVC correctly place the prototyped function in the enclosing namespace:
namespace ns
{
void foo();   // all fine
void bar()
{
    foo();
}
void foo() { }
} // namespace ns
                The standard is clear about this point:
3.3.2/11: (..) Function declarations at block scope and variable declarations with the extern specifier at block scope refer to declarations that are members of an enclosing namespace (...)
Consequently:
void bar()
{
    void foo();   // should refer to ns::foo() according to 3.3.2/11
    foo();
}
and the linking should refer to the separately compiled function which has the same signature:
1.3.17 signature:
<function>name, parameter type list , and enclosing namespace (if any) [Note: Signatures are used as a basis for name mangling and linking.—end note ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With