C ++外部/多个定义

时间:2010-09-03 19:47:36

标签: c++ extern

我正在尝试使用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无法链接,我得到 index value 的多重定义错误。我只是想了解这些差异。

3 个答案:

答案 0 :(得分:7)

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

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

修改

参见Charle对C ++标准中定义的外部怪异的真实定义的回应。

答案 1 :(得分:7)

应用于括号括起的声明序列的链接说明符(即extern "C"extern "C++")对所附声明是否为定义没有影响,但是应用于单个声明的 linkage-specifier 被视为extern说明符,用于确定声明是否也是一个定义。 (C ++ 03第7.5段)

所以:

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.

答案 2 :(得分:3)

我不确定为什么第二个有效,但你想要

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

因为您只想 声明 indexvalue,而不是 定义 他们。 (请参阅 this answer 了解差异。)