Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VS2008(+?) compiler bug with templated functions and 'using namespace'

I've found this odd case of some code (below) doesn't compile under Visual Studio 2008 and produces an "error C2872: 'Ambiguity' : ambiguous symbol" on line 12.

Removing the using namespace RequiredNamespace on the last line fixes the error, but I'd expect that putting using namespace at the end of a file should have no effect. It also relies on AnotherFunction being a template function, so I expect the compiler is generating the templated functions in the wrong scope, or isn't resetting the list of namespaces being used before doing so.

The same code compiles under GCC.

Both compilers seem to generate the code for TemplatedFunction after the using namespace Namespace definition, at least as far as I can tell by introducing errors and looking at the order they're output.

namespace Ambiguity
{
    class cSomeClass
    {
    };

    template<class T>
    void TemplatedFunction(T a)
    {
        // this is where the error occurs, the compiler thinks Ambiguity
        // might refer to the class in RequiredNamespace below
        Ambiguity::cSomeClass(); 
    }
}

namespace RequiredNamespace 
{
    // without a namespace around this class, the Ambiguity class 
    // and namespace collide
    class Ambiguity
    {
    };
}

int main()
{
    // to force the templated function to be generated
    Ambiguity::TemplatedFunction(4); 
}

// removing this removes the error, but it shouldn't really do anything
using namespace RequiredNamespace; 

Obviously this is a manufactured example, but the original is extracted from a real case where the using namespace is in a auto-generated file produced by 3rd party code.

Is this a bug in the compiler?

like image 958
eAi Avatar asked Sep 14 '10 11:09

eAi


1 Answers

I agree that it is a bug, but some insight into what is going on can be obtianed by generating the assembly listing corresponding to your file (use the /Fa option of cl.exe).

So, comment out the using declaration, generate the .asm file and open it in a text editor. Scan the file and you can see that the instantiation of the template is at the bottom of the file (it starts with ??$TemplatedFunction@H@Ambiguity@@YAXH@Z PROC), and it is under the assembly generated for the main function (starts with _main PROC). The error message said "see reference to function template instantiation", so it is referring to the instantiation of the template function, and the assembly listing makes clear this instantiation is at the bottom of the file.

Now, edit the code to replace the template function with NonTemplatedFunction(int a) and compile, generating an assembly listing. View the assembly listing and you will see the assembly code generated for NonTemplatedFunction(int a) appears above _main PROC.

What does all this babble mean? When the Visual Studio 2008 compiler turns your templates into actual code, it is effectively appending some code to the end of your file after your using declaration. Your using declaration means the names in the automatically generated code are "ambiguous". The process gcc uses to instantiate templates obviously avoids this problem.

like image 74
mcdave Avatar answered Sep 30 '22 13:09

mcdave