C++外部/多重定义

发布于 2024-09-16 22:37:10 字数 487 浏览 2 评论 0原文

我正在尝试使用 externs 与 C++ 中的 Ada 进行交互。这两种实现有什么区别?

实现 A

namespace Ada
{
    extern "C"
    {
        int getNumber();
        int index;
        int value;
    }
}

实现 B

namespace Ada
{
    extern "C"
    {
        int getNumber();
    }
    extern "C" int index;
    extern "C" int value;
}

两个实现都编译得很好。但是 Impl-A 无法链接,我收到 indexvalue 的多重定义错误。我只是想了解其中的差异。

I am trying to interface to Ada in C++ using externs. What is the difference between these two implementations?

Implementation A

namespace Ada
{
    extern "C"
    {
        int getNumber();
        int index;
        int value;
    }
}

Implementation B

namespace Ada
{
    extern "C"
    {
        int getNumber();
    }
    extern "C" int index;
    extern "C" int value;
}

Both implementations compile just fine. But Impl-A fails to link, I get a multiple definition error for index and value. I'm just trying to understand the differences.

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

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

发布评论

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

评论(3

一腔孤↑勇 2024-09-23 22:37:10

extern“C”仅传达用于 extern“C”块内的代码的链接约定。该块中的任何内容都将被链接起来,就好像它是纯 c 一样。令人困惑的是, extern int 完全不同。这意味着你保证在某处有一个实际的 int 命名索引和一个实际的 int 命名值,但在这里找不到它们。在您的实现-A 中,整数实际上不是第二种意义上的外部 - 外部“C”仅意味着它们提供严格的 c 链接约定。

相同的关键字但完全不同的用途,这是不幸的,因为它会导致像这样的奇怪问题。混合它们是合法的(显然),但它们的行为方式并不像它们的名字所暗示的那样。

编辑

请参阅 Charle 的回复,了解 C++ 标准中定义的外部怪异的真正定义。

extern "C" only conveys the linking conventions to use for the code within the extern "C" block. Anything in that block will be linked against as if it were pure c. Confusingly, extern int is totally different. It means that you promise there is an actual int named index and an actual int named value somewhere, but they cannot be found here. In your implementation-A the ints are actually not extern in the second sense - the extern "C" only implies that they provide a strict c linking convention.

Same keyword but totally different uses, which is unfortunate since it leads to weird issues like this. Mixing them is legal (obviously), but they don't behave together the way that their name implies.

EDIT

See Charle's response for the true definition of the extern weirdness as defined in the C++ standard.

做个少女永远怀春 2024-09-23 22:37:10

应用于大括号内的声明序列的链接说明符(即 extern "C"extern "C++")对于是否所包含的声明是否是定义,但是应用于单个声明的链接说明符被视为extern说明符,以便确定声明是否也是定义。 (C++03 的 7.5 第 7 段)

因此:

extern "C" { int a; } // a is declared and defined

extern "C" int a; // a is just a declaration (as if extern int a;)

extern "C" int a = 0; // a is a definition because of the initializer.

A linkage-specifier (i.e. extern "C" or extern "C++") applied to a brace enclosed sequence of declarations has no effect on whether the enclosed declarations are definitions or not, however a linkage-specifier applied to a single declaration is treated as an extern specifier for the purposes of determining whether a declaration is also a definition. (7.5 para 7 of C++03)

So:

extern "C" { int a; } // a is declared and defined

extern "C" int a; // a is just a declaration (as if extern int a;)

extern "C" int a = 0; // a is a definition because of the initializer.
樱桃奶球 2024-09-23 22:37:10

我不知道为什么第二个有效,但你想要,

namespace Ada
{
    extern "C"
    {
        int getNumber();
        extern int index;
        extern int value;
    }
}

因为你只想声明 indexvalue ,而不是定义它们。 (请参阅这个答案的差异。)

I'm not sure why the second works, but you want

namespace Ada
{
    extern "C"
    {
        int getNumber();
        extern int index;
        extern int value;
    }
}

because you only want to declare index and value, not define them. (See this answer for the difference.)

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