C++;外部/多个定义 我试图用C++来与C++中的艾达接口。这两种实现之间的区别是什么
实施AC++;外部/多个定义 我试图用C++来与C++中的艾达接口。这两种实现之间的区别是什么,c++,extern,C++,Extern,实施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; } 这两种实现都可以很好
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链接失败,我得到了索引和值的多定义错误。我只是想了解两者的区别。我不知道为什么第二种方法有效,但你想知道
namespace Ada
{
extern "C"
{
int getNumber();
extern int index;
extern int value;
}
}
因为您只想声明索引
和值
,而不想定义它们。(请参见了解区别。)外部“C”仅传递用于外部“C”块内代码的链接约定。该块中的任何内容都将被链接,就像它是纯c一样。令人困惑的是,extern int完全不同。这意味着您承诺在某个地方有一个实际的int命名索引和一个实际的int命名值,但在这里找不到它们。在您的实现-A中,int实际上不是第二种意义上的extern-extern“C”只意味着它们提供了严格的C链接约定
相同的关键字,但完全不同的用法,这是不幸的,因为它会导致像这样的奇怪问题。将它们混合在一起是合法的(显然),但它们的行为并不像它们的名字所暗示的那样
编辑
<> P> > Charle对C++定义中的外部怪异的真实定义的响应。 < P>一个链接规范(即<代码>外部)C“<代码> >或代码>外部> C++ >代码>对声明的括号封闭的序列不会影响所附声明是否定义,但是,为了确定声明是否也是定义,应用于单个声明的链接说明符被视为extern
说明符。(C++03第7段第7.5节)
因此:
第二个可能有效,因为
extern“C”
对变量没有任何意义,所以“C”
被忽略了?只是一个猜测。我认为更一般的问题是为什么外部块不设置所有的外部。@linuxuser:不应该extern“blah”T foo
只是告诉链接器链接foo
要遵循哪个链接约定<代码>外部T条,OTOH告诉编译器它不应该担心条
的存在,链接器(希望)会在某处找到一个。后者将使用(隐式)“C++”链接。@ OLI:我认为C++实现通常将变量的类型转换成其名称,而不是C。因此,代码> Extn“C”INTX/CONT>做了一些事情:它要求链接器使用C的链接来查找<代码> x< /C>。这与它们的类型无关,主要与它们的名称空间有关。如果它们没有损坏,如何区分::index
和Ada::index
呢?extern“C”
表示它们没有区别,但实际上声明的是同一个对象。@彼得:我也这么认为,但这仍然不能说明为什么第二个版本的代码可以工作。@sbi我不确定我是否经过了充分的测试,可以说第二个版本可以工作。。。我已经读了几遍这个答案,但我不明白(例如,extern“C”
应用于单个声明和extern“C”
应用于括号括起来的声明列表之间的区别。显然我错了(因为它被接受了),但我看不出它是如何回答最初的问题的。@charles-哎呀,这并不是说不解决实现-B。实际上我更喜欢你的回答,因为它定位了引用。我的只是试图回答为什么第一个实现不起作用,而不是为什么第二个实现起作用。
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.