Visual C++ 2015 linker error when forward declaring a struct as class

后端 未结 1 1413
小蘑菇
小蘑菇 2021-01-12 12:00

I have the following code (more than one file involved)...

//--- SomeInterface.h
struct SomeInterface
{
  virtual void foo() = 0;
  virtual ~SomeInterface(){         


        
相关标签:
1条回答
  • 2021-01-12 12:15

    I've just been facing the same problem with both VC++ 2010 and VC++ 2017, and after some tests I've found that the problem resides in the symbol name the compiler gives to structs and classes internally.

    Here a minimum example consisting in three files:

    main.cpp

    #include "bar.h"
    struct Foo {};
    
    int main() {
      Foo foo;
      bar(&foo);
      return 0;
    }
    

    bar.h

    class Foo;
    void bar(Foo* f);
    

    bar.cpp

    #include "bar.h"
    
    void bar(Foo* foo) {}
    

    When the project is compiled the following errors and warnings appear:

    warning C4099: 'Foo': type name first seen using 'class' now seen using 'struct'

    see declaration of 'Foo'

    error LNK2019: unresolved external symbol "void __cdecl bar(struct Foo *)" (?bar@@YAXPAUFoo@@@Z) referenced in function _main

    fatal error LNK1120: 1 unresolved externals

    Now, I swapped the struct and class declarations, so main.cpp and bar.h are now:

    main.cpp

    #include "bar.h"
    class Foo {};
    
    int main() {
      Foo foo;
      bar(&foo);
      return 0;
    }
    

    bar.h

    struct Foo;
    void bar(Foo* f);
    

    As expected, the error still pops up:

    error LNK2019: unresolved external symbol "void __cdecl bar(class Foo *)" (?bar@@YAXPAVFoo@@@Z) referenced in function _main

    BUT, and this is the interesting part, see that the symbols for the expected function (the one used in main()) in each case differ:

    • ?bar@@YAXPAUFoo@@@Z (when the parameter is a struct)

    • ?bar@@YAXPAVFoo@@@Z (when the parameter is a class)


    Conclusion

    The compiler gives slightly different names if the type is a struct or a class.

    The linker then cannot find the proper definition because it is looking for a different one: bar.cpp defines one with the forward declaration, but for the moment it is called in main.cpp the actual declaration has taken placed, so a different function name is given in the symbols table.

    0 讨论(0)
提交回复
热议问题