MSVC and Templates

Take a look at this snippet of code. Does it look valid to you? On first glance, it might. But if you run it through your compiler… hmm, wait.. MSVC thinks this is valid code too.

template <typename A>
class Foo
{
public:
    Foo()
    {
        Bar<A> b;
        b.method();
    }
};

template <typename A>
class Bar
{
public:
    void method() {}
};

int main( int argc, char** argv )
{
    Foo<char> f;
    return 0;
}

I’m sure we all know how MSVC is lax when it comes to using typename. The issue here, though, is that Foo’s constructor refers to Bar, which hasn’t been declared. GCC complains with error: ‘Bar’ was not declared in this scope. MSVC, however, apparently lets this slide and only parses the code for Foo when it actually instantiates the template. It seems that GCC actually does the parsing work up front, and only emits code when the template is instantiated, whereas MSVC saves the parsing for when the template is actually instantiated.

So, be warned. If you’re developing (or maintaining…) template-heavy code that’s supposed to be portable with MSVC, compile early and often with GCC.

©2011-2020 Justin C. Miller.   What a horrible night to have a curse.