Search code examples
c++templatesvisual-c++visual-c++-2010

compiler stack overflow on template code


While working on my own type erasure iterator, I ran into an issue where the compiler (MSVC10) crashed with a stack overflow on this code:

struct base {};  //In actual code, this is a template struct that holds data
template<class category, class valuetype>  
    struct any;  //In actual code, this is abstract base struct
template<class basetype, class category, class valuetype> 
    struct from; //In actual code, this is function definitions of any

template<class valuetype>
struct any<void,valuetype>
{ void a() {} };
template<class category, class valuetype>  
struct any
    : public any<void,valuetype> //commenting this line makes it compile
{ void b() {} };        

template<class basetype, class valuetype>
struct from<basetype,void,valuetype>
    : public base  //commenting out _either_ of these makes it compile
    , public any<void,valuetype>
{ void c() {} };

int main() {
    from<int, void, char> a;
    a.a();
    a.c();
    any<int, char> b;
    b.a();
    b.b();
    return 0;
}

Obviously, I've removed everything I can where the bug remains. (Origional code was 780+ lines) Removing any remaining template parameters causes the code to compile.

The full error message is:

main.cpp(23): fatal error C1063: compiler limit : compiler stack overflow
    main.cpp(20) : see reference to class template instantiation 'from<basetype,void,valuetype>' being compiled

IDEOne compiles it fine. I've heard that MSVC implemented two-phase lookup wrong, which seems relevant, but doesn't explain why it compiles when I remove the line that makes from inherit from base. Can anyone teach me why MSVC10 won't compile this? What did I do that I should be avoiding?


Solution

  • As a workaround, consider introducing an additional class between the unspecialized any and the specialization with category = void:

    template <class valuetype>
    class detail_void_any
        : public any<void, valuetype>
    {
    };
    
    
    template<class category, class valuetype>
    class any
        : public detail_void_any<valuetype>
    {
    };
    

    The following complete program should compile without error:

    class base {};      // Data Holder (in reality it's templated, so required)
    template<class category, class valuetype>  
            class any;  // Virtual Function Interface
    template<class basetype, class category, class valuetype> 
            class from; // Virtual Function Implementation
    
    template<class valuetype>
    class any<void,valuetype>
    {};
    
    
    template <class valuetype>
    class detail_void_any
        : public any<void, valuetype>
    {
    };
    
    template<class category, class valuetype>
    class any
        : public detail_void_any<valuetype>
    {
    };
    
    template<class basetype, class valuetype>
    class from<basetype,void,valuetype>
            : public base  //commenting out _either_ of these makes it compile
            , public any<void,valuetype>
    {}; //this is line 23, where the compiler crashes
    
    int main() {return 0;}