【问题标题】:Problem with extern keyword in C++C++中extern关键字的问题
【发布时间】:2010-03-27 00:42:20
【问题描述】:

以下两个声明有什么区别?我认为它们是等效的,但是第一个示例有效,而第二个示例无效。我的意思是它编译并运行,但位图显示代码显示为空白。我还没有通过它,但我错过了一些明显的东西吗? GUI_BITMAP 是描述位图的简单结构。这适用于 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 上编译,并出现关于缺少默认构造函数的错误。所以我猜想“extern”关键字、结构和 C++ 有一些我不明白的微妙之处。如果外部区域的东西是函数,那么两个样本应该是一样的吧?

【问题讨论】:

    标签: c++ visual-c++ keyword extern


    【解决方案1】:

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

    This page 的 ARM 文档很好地描述了这个问题 - 我预计你的情况会发生类似的行为:

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

    编辑:更多搜索发现此问题是由于违反“One Definition Rule”引起的,因此编译器/链接器不需要通知您该问题。这使您的问题与this one 重复。

    【讨论】:

    • 感谢回复,但是这里没有用到库对象,这都是我的代码,C和C++的混合。我最初的问题仍然存在 - 示例 1 和示例 2 之间有什么区别 - 我认为它们应该生成完全相同的代码?如果这些东西是函数而不是结构 - 它们是同一个东西,对吧?
    • @Jeff,对您的问题的快速回答是,不,这两个不一样,这就是您看到问题的原因。在第二种情况下,您只需修改 {} 中的语句以使用 C 的链接约定。在第一个示例中,您正在执行 plus 表示变量在其他地方声明。 msdn.microsoft.com/en-us/library/0603949d(VS.80).aspx
    【解决方案2】:

    第二个例子可能等同于第一个例子,在 const 前面多了一个 extern。在第一种情况下,编译器可能结合了 extern 的两种用法。在第二种情况下,我会假设编译器不会出于任何原因排除 extern 范围 extern 中的所有内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-16
      • 2020-04-14
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      相关资源
      最近更新 更多