C++中extern关键字的问题

Jef*_*eff 5 c++ keyword extern visual-c++

以下两个声明之间的区别是什么?我认为它们是等价的,但第一个样本有效,第二个没有.我的意思是它编译并运行,但位图显示代码显示为空白.我还没有介入它,但我错过了一些明显的东西吗?GUI_BITMAP是一个描述位图的简单结构.这适用于VC++ 2005,但我认为它在VC++ 2008中也失败了.抓住这个......

样本1:

extern "C" const GUI_BITMAP bmkeyA_cap_active;
extern "C" const GUI_BITMAP bmkeyA_cap_inactive;
Run Code Online (Sandbox Code Playgroud)

样本2:

extern "C" 
{
   const GUI_BITMAP bmkeyA_cap_active;
   const GUI_BITMAP bmkeyA_cap_inactive;
};
Run Code Online (Sandbox Code Playgroud)

编辑:更多的探索表明第二个例子是创建结构,而第一个例子是指外部结构.第二个示例无法链接,因为全局范围内有两个具有相同名称的变量.但事实并非如此,它会向放弃的显示代码发送零填充结构.嗯.....

编辑2:通过另一个编译器(IAR)运行相同的代码实际上无法在示例2上编译,但错误的是缺少默认构造函数.所以我猜测有一些关于"extern"关键字,结构和C++的细微之处,我没有得到.如果外部区域的东西是功能,那么两个样本是否相同?

Car*_*rum 3

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

ARM 文档的此页很好地描述了该问题 - 我预计您的情况也会发生类似的行为:

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

编辑:更多搜索发现此问题是由于违反“单一定义规则”而引起的,因此编译器/链接器不需要通知您该问题。这使得你的问题与这个问题重复。