我正在尝试使用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 的多重定义错误。我只是想了解这些差异。
答案 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;
}
}
因为您只想 声明 index
和value
,而不是 定义 他们。 (请参阅 this answer 了解差异。)