C ++中extern关键字的问题

时间:2010-03-27 00:42:20

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

以下两个声明之间的区别是什么?我认为它们是等价的,但第一个样本有效,第二个没有。我的意思是它编译并运行,但位图显示代码显示为空白。我还没有介入它,但我错过了一些明显的东西吗? 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 ++的细微之处,我没有得到。如果外部区域的东西是函数,那么两个样本是否完全相同?

2 个答案:

答案 0 :(得分:3)

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

ARM文档的

This page很好地描述了问题 - 我希望你的案例中会发生类似的行为:

  

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

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

答案 1 :(得分:0)

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