代码之家  ›  专栏  ›  技术社区  ›  Gregory Pakosz

内联非成员函数内的本地类使用MSVC2005生成lnk2005

  •  2
  • Gregory Pakosz  · 技术社区  · 15 年前

    显然,MSVC2005未能内联导致lnk2005的本地类成员函数。

    我在编译以下内容时遇到了这个lnk2005错误:

    common.h 内容:

    inline void wait_what()
    {
      struct wtf
      {
        void ffffuuu() {}
    
      } local;
    }
    

    foo.cpp 内容:

    #include "common.h"
    
    void foo()
    {
      wait_what();
    }
    

    bar.cpp 内容:

    #include "common.h"
    
    void bar()
    {
      wait_what();
    }
    

    lnk2005.cpp含量:

    // forward declarations
    void foo();
    void bar();
    
    int main()
    {
      foo();
      bar();
    
      return 0;
    }
    

    错误消息为:

    error LNK2005: "public void __thiscall `void__cdecl wait_what(void)'::`2'::wtf::ffffuuu(void)" (?ffffuuu@wtf?1??wait_what@@YAXXZ@QAEXXZ) already defined in bar.obj
    

    关于地方等级,ISO IEC 14882-2003规定:

    9.8本地类声明

    类可以在函数定义内定义;这样的类称为 地方的 班级。本地类的名称是其封闭范围的本地名称。本地类在封闭范围内,对函数外部的名称具有与封闭函数相同的访问权限。本地类中的声明只能使用类型名、静态变量、外部变量和函数以及封闭范围中的枚举器。

    封闭函数对本地类的成员没有特殊的访问权;它遵循通常的访问规则(第11条)。局部类的成员函数应在其类定义中定义(如果完全定义)。

    我错过什么了吗?

    在我看来,这是一个编译器错误。GCC和MSVC2008编译得很好。但是,我想知道他们是真的将调用内联,还是在链接阶段丢弃这两个符号中的一个。有趣的是,您可以注意到甚至没有调用这个本地类成员函数。

    我想知道MSVC2005是否有解决方法。我试图在msdn中搜索这个典型的问题,但没有成功:我甚至找不到编译器的已知bug列表。


    附件: LNK2005.zip

    2 回复  |  直到 15 年前
        1
  •  3
  •   Alon    15 年前

    它是Visual Studio 2005中的一个bug,已在vs 2008中修复

        2
  •  1
  •   moswald Jarod42    15 年前

    我觉得它像个虫子。也许这就是它在VS2008中工作的原因。(顺便说一句,微软,这是打破Visual Studio中IDE/编译器依赖性的一个很好的理由。)

    对于解决方法,尝试显式添加 inline ,或不嵌入 wait_what .

    推荐文章