代码之家  ›  专栏  ›  技术社区  ›  Jeff

C++中的外部关键字问题

  •  5
  • Jeff  · 技术社区  · 16 年前

    下面两个声明有什么区别?我认为它们是等价的,但第一个样本有效,而第二个不有效。我是说它编译并运行,但是位图显示代码显示为空。我还没有跨过这一步,但我是否遗漏了一些显而易见的东西?gui_位图是描述位图的简单结构。这是针对vc++2005的,但我认为它在vc++2008中也失败了。在这个上面搔我的头…

    样品1:

    extern "C" const GUI_BITMAP bmkeyA_cap_active;
    extern "C" const GUI_BITMAP bmkeyA_cap_inactive;
    

    样品2:

    extern "C" 
    {
       const GUI_BITMAP bmkeyA_cap_active;
       const GUI_BITMAP bmkeyA_cap_inactive;
    };
    

    编辑: 更多的探索表明,第二个示例是创建结构,而第一个示例是指外部结构。第二个示例应该无法链接,因为全局范围中有两个同名的变量。但它没有,它发送一个零填充的结构到显示代码,显示代码放弃。六羟甲基三聚氰胺六甲醚。。。。。

    编辑2: 通过另一个编译器(IAR)运行相同的代码实际上无法在示例2上编译,错误是缺少默认构造函数。所以我猜想,“外文”关键字、结构和C++有一些微妙之处。如果外部区域的东西是函数,那么两个样本是相同的,对吗?

    2 回复  |  直到 16 年前
        1
  •  3
  •   Carl Norum    16 年前

    你的链接器可能正在悄悄地解决背后的重复符号。您可能会从供应商那里获得静态库,并且必须将它们与您的程序链接起来—对于有两个这样的库并且它们都定义了一个公共符号的情况,有什么解决方案?链接器只会解决这个问题,选择一个或另一个定义,然后让您处理这个问题。如何处理应用程序的链接阶段?如果直接链接.o文件,而不是在链接最终应用程序之前将其放入中间库,则可能会获得更好的结果。

    This page ARM文档中很好地描述了这个问题—我希望在您的案例中也会发生类似的行为:

    不同库对象中的符号的多个定义不一定被检测到。一旦链接器找到一个合适的符号定义,它就会停止寻找其他符号。假设由于其他原因未加载包含重复符号的对象,则不会发生错误。这是有意的,在某些情况下特别有用。

    编辑:更多的搜索发现此问题是由于违反了“ One Definition Rule ,因此不需要编译器/链接器通知您该问题。所以你的问题是 this one .

        2
  •  0
  •   MSN    16 年前

    第二个示例可能相当于第一个在常量前面有一个额外的外部。在第一种情况下,编译器可能结合了extern的两种用法。在第二种情况下,我假设编译器不会出于任何原因将外部作用域extern中的所有内容强制插入。