C++ 中 extern 关键字的问题

发布于 2024-08-26 22:52:53 字数 706 浏览 3 评论 0原文

以下两个声明有什么区别?我认为它们是等效的,但第一个示例有效,而第二个示例无效。我的意思是它编译并运行,但位图显示代码显示空白。我还没有经历过它,但我是否遗漏了一些明显的东西? 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++ 有一些我不明白的微妙之处。如果外部区域中的事物是函数,那么两个样本将是相同的,对吗?

What's the difference between the following two declarations? I thought they were equivalent, but the first sample works, and the second does not. I mean it compiles and runs, but the bitmap display code shows blank. I have not stepped through it yet, but am I missing something obvious? GUI_BITMAP is a simple structure describing a bitmap. This is for VC++ 2005, but I think it fails in VC++ 2008 also. Scratching my head on this one...

Sample 1:

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

Sample 2:

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

Edit: More exploring has shown that the second example is creating the structs, while the first is referring to external structs. The second example should fail to link, since there are two variables at global scope with the same name. But it doesn't, it sends a zero filled struct to the display code which gives up. Hmmm.....

Edit 2: Running the same code through another compiler (IAR) actually failed to compile on Sample 2, with an error about missing a default constructor. So I'm guessing there is something subtle about the "extern" keyword, structs, and C++ that I don't get. If the things in extern area were functions the two samples would be identical right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最后的乘客 2024-09-02 22:52:53

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

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

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

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

Your linker may is silently resolving the duplicate symbols behind your back. You might get static libraries from a vendor and have to link them with your program - what is the solution for the situation where you have two such libraries and they both define a common symbol? The linker will just resolve that, choosing one or the other definition, and leaving you to deal with the fallout. How are you handling the link stage of your application? You may have better results if you link .o files directly instead of putting them into intermediate libraries before linking the final application.

This page of the ARM documentation describes the problem well - I expect similar behaviour is happening in your case:

Multiple definitions of a symbol in different library objects are not necessarily detected. Once the linker has found a suitable definition for a symbol it stops looking for others. Assuming the object containing the duplicate symbol is not loaded for other reasons no error will occur. This is intentional and particularly useful in some situations.

Edit: More searching has turned up that this problem is caused because of a violation of the "One Definition Rule", and as a result the compiler/linker aren't required to inform you of the problem. That makes your question a duplicate of this one.

情未る 2024-09-02 22:52:53

第二个示例可能与第一个示例等效,但在 const 前面有一个额外的 extern。在第一种情况下,编译器可能结合了 extern 的两种用法。在第二种情况下,我假设编译器不会出于任何原因对 extern 范围 extern 中的所有内容进行男性化。

The second example might be equivalent to the first with an extra extern in front of the const. In the first case, the compiler is probably combining the two uses of extern. In the second case, I would assume the compiler doesn't male everything in the extern scope extern for whatever reason.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文