Function definition not found for a function declared inside unnamed namespace – how to resolve? (Visual Studio 2015)

The green squiggles don’t tell you that there’s an error, they tell you that there’s an opportunity for the new refactoring tools to do something. (Red squiggles indicate an error.) In this case, they’re informing you that there is no definition matching the declaration of test2, so the IDE is offering to generate one.

This happens to point out an error that was always there in the code, although Visual Studio might be behaving in a non-conforming manner.

So what happens? The problem is that the declarations in the unnamed namespace do not declare the same functions that you later define in the global namespace. The refactoring tools recognize this and offer to generate a definition for the declared functions.

However, the whole thing still compiles, due to the Microsoft compiler accepting two strictly illegal pieces of code. First, using the namespace prefix on the first declaration of a function is not allowed. The code in main then presumably calls the functions. As Alex M showed in his answer, GCC won’t accept this either, since the call is ambiguous. The Microsoft compiler appears to accept it, either treating the definition as a definition matching the declaration in the unnamed namespace (remember, the tools of the IDE, IntelliSense and the refactory, used the more compliant EDG front-end, not the parser the actual compiler uses, which means that the refactory can say that the declaration has no definition, while the compiler treats the definition as matching the declaration), or just preferring the global version to the namespaced version.

It’s easy to distinguish the two cases, by the way. Rearrange the code so that main comes before the function definitions. This will resolve the ambiguity in GCC, because only the namespaced function is declared (and not defined, so you should get a linker error). It will also lead to a linker error in the Microsoft compiler, if it just prefers the global version, but will still compile if it treats the declaration and definition as matching.

The solution to all this is very simple: when defining functions declared in the unnamed namespace, just reopen the namespace instead of trying to define the functions outside.

Leave a Comment