Forward a function declaration in a namespace inside another function in this namespace

I have two source files, a.cpp and b.cpp . In a.cpp , I have a foo function:

 namespace ns { void foo() { std::cout << "foo!"; } } 

In b.cpp , I have another function in the ns namespace in which I would like to prototype and call foo :

 namespace ns { void bar() { void foo(); foo(); } } 

While the above is syntactically correct, it leads the compiler to think that foo is in the global namespace (or at least this is what I deduced from the linker errors that I get when I do this). My first two ideas for fixing were void ns::foo(); and namespace ns { void foo(); } namespace ns { void foo(); } , but not one of them is valid. Is it possible to correctly prototype this function inside bar ?

Please note that I know that I can just transfer this to a file area or header file, many questions have been 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 of the tests I did, and our discussion in the comments, I think this is an MSVC bug. For comparison:

 namespace ns { void bar() { void foo(); // link error, MSVC assumes global namespace foo(); } void foo() { } } // namespace ns 

This is not performed as previously indicated. However, moving the prototype from the function makes MSVC correctly place the prototyped function in the namespace:

 namespace ns { void foo(); // all fine void bar() { foo(); } void foo() { } } // namespace ns 
+5
source share
1 answer

The standard is clear about this point:

3.3.2 / 11: (..) Declaring functions in the block area and declaring variables using the extern specifier in the scope field refers to declarations that are members of the encompassing namespace (...)

Hence:

 void bar() { void foo(); // should refer to ns::foo() according to 3.3.2/11 foo(); } 

and the link should refer to a separately compiled function that has the same signature:

1.3.17 signature: <function> name, list of parameter types and encompassing namespace (if any) [Note: signatures are used as the basis for name mangling and linking.-end note]

+4
source

Source: https://habr.com/ru/post/1239636/


All Articles