Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;外部/多个定义 我试图用C++来与C++中的艾达接口。这两种实现之间的区别是什么_C++_Extern - Fatal编程技术网

C++;外部/多个定义 我试图用C++来与C++中的艾达接口。这两种实现之间的区别是什么

C++;外部/多个定义 我试图用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; } 这两种实现都可以很好

实施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链接失败,我得到了索引和值的多定义错误。我只是想了解两者的区别。

我不知道为什么第二种方法有效,但你想知道

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.