Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.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链接 我遇到了一个工作(带有XLC8和MSFT9编译器)代码,包含一个C++文件,其中的函数用C链接和引用参数定义。这是错误的,因为引用是C++的。所讨论的函数是从C代码调用的,在C代码中,它被声明为使用指向同一类型的指针参数来代替引用参数_C++_C_Pointers_Compiler Construction_Reference - Fatal编程技术网

C++;通过引用参数和C链接 我遇到了一个工作(带有XLC8和MSFT9编译器)代码,包含一个C++文件,其中的函数用C链接和引用参数定义。这是错误的,因为引用是C++的。所讨论的函数是从C代码调用的,在C代码中,它被声明为使用指向同一类型的指针参数来代替引用参数

C++;通过引用参数和C链接 我遇到了一个工作(带有XLC8和MSFT9编译器)代码,包含一个C++文件,其中的函数用C链接和引用参数定义。这是错误的,因为引用是C++的。所讨论的函数是从C代码调用的,在C代码中,它被声明为使用指向同一类型的指针参数来代替引用参数,c++,c,pointers,compiler-construction,reference,C++,C,Pointers,Compiler Construction,Reference,简化示例: C++文件: C文件: 现在,街道上的单词是大多数C++编译器,在引擎盖下实现引用,就像指针一样。这是不是纯粹的运气,这个代码的工作原理,或者说它在C++规范中的某个地方,当你用引用参数和C链接定义函数时,结果是什么?我还没有找到任何关于这方面的信息。在很多情况下,但并非所有情况下,引用都可以通过“自动取消引用”指针实现。任何特定编译器都用C链接处理函数,而引用参数在C++标准中是不被保证的,并且应该将其视为实现细节。 如果需要在不依赖实现细节的情况下执行此操作,那么编写一个接收指针

简化示例

C++文件:

C文件:


现在,街道上的单词是大多数C++编译器,在引擎盖下实现引用,就像指针一样。这是不是纯粹的运气,这个代码的工作原理,或者说它在C++规范中的某个地方,当你用引用参数和C链接定义函数时,结果是什么?我还没有找到任何关于这方面的信息。

在很多情况下,但并非所有情况下,引用都可以通过“自动取消引用”指针实现。任何特定编译器都用C链接处理函数,而引用参数在C++标准中是不被保证的,并且应该将其视为实现细节。 如果需要在不依赖实现细节的情况下执行此操作,那么编写一个接收指针并调用函数的转发函数并不困难:

void real_f(int& n) {
  n++;
}
extern "C" void f(int* p) { // called from C code
  real_f(*p);
}
引用是对象的备用名称。从技术上讲,C中没有任何东西可以直接映射到C++引用。p> 引用的明显实现是作为(常量)指针,每次使用它时都会取消引用。因此,根据编译器实现引用的方式,代码可能会正常工作。但这是不正确的


解决方案是编写一个C函数,接收一个真实对象或指向该对象的指针,并从这个函数调用C++函数。

< P>这是Bjarne Stroustrup关于引用的一个定义:

大多数引用都是使用指针变量实现的;引用通常会占用一个字的内存。但是,纯粹在本地使用的引用可以而且通常会被优化器消除。”

例如:

 struct S 
 { 
    int a;
    int b[100]; 
 };  // just an example

 void do_something(const vector<S>& v)
 {
    for (int i=0; i<v.size(); ++i)
    {
        int(&p)[100] = v[i].b;
        for (int j=0; j<100; ++j) 
           cout <<p[j];
    }
 }
结构
{ 
INTA;
int b[100];
};  // 只是一个例子
void do_某事(const vector&v)
{
对于(int i=0;i我的n3000.pdf副本(从),在第7.5节-链接规范中有这样一句话:

<P>9。Linkage从C++到定义对象 其他语言和定义的对象 C++语言中的其他语言是 实现定义和 语言相关。仅当 二者的对象布局策略 语言实现是相似的 这样的联系可以达到足够的程度

<>因为C和C++是不同的语言,这意味着你不能依赖普通编译器的这个“特性”。 同一节中的注释5(重点):

如果两个声明声明函数 同名 待修改的参数类型列表(8.3.5) 同一命名空间的成员或 将具有相同名称的对象声明为 是同一命名空间的成员,并且 声明给出了名称 不同语言之间的联系 程序格式不正确;无诊断 如果出现声明,则需要 在不同的翻译单位中

因此,我要说的是,您所做的并不能保证按照标准工作,并且编译器也不需要为您给出的示例打印诊断,因为声明在不同的翻译单元中


仅供参考,gcc和雪豹上的g++版本4.2.1“对我有用”。

我想你已经得到了一些很好的答案,所以请在你的问题上指出一些额外的东西

我拙劣的理解是extern仅仅创建了一个C符号

因此,即使我添加了一个类对象,您的示例仍然“似乎有效”(gcc/g++),我必须尝试ir才能相信这一点:

class A {};

extern "C" void f(int &i, A a) {
    i++;
}

从我所看到的C++标准的第7.5部分(链接规范)没有任何说明。它不能保证,但它不一定是错误的。其他语言如何调用C++函数(包括<代码>外)C“< /代码> C++函数”就C++而言,函数已经被正确地声明和调用。这是一个实现问题,不管你是否应该,或者不依赖于它,都会根据项目需求而变化。你是说代码> int(& p)[100 ]=v[i],b;< />代码;也S/,//和V.siz()。如果你能给出一个更完整的引文就好了。斯特劳斯特鲁普在哪里说的?(网站,或书名,版本和页码)另一方面,我们已经知道引用通常被实现为指针。这就是为什么问题中的代码像今天这样工作。我看不出你试图用这个答案表达的观点,特别是关于带有C链接的函数的参数。完全正确的引用,但请注意它也有一个优点:因为它是实现的不管怎么说,如果它能工作,它也能工作。是的,但可能是因为它能与特定版本的编译器一起工作?我试图查看gcc文档,但找不到任何信息。据我所知,这个问题更多的是一个“理论”问题问题,试图找出标准是否允许这样的声明。我怀疑OP是否想在真实的代码中做这样的事情,因为这样做很容易避免。代码正在生产中并且可以工作,但我希望保持代码标准的兼容性,因为新的平台或编译器可能会成为未来的目标。在这种情况下,我认为标准很清楚,所以如果更改代码很容易,你应该这么做。@Alok,是的。这是最好的。
 struct S 
 { 
    int a;
    int b[100]; 
 };  // just an example

 void do_something(const vector<S>& v)
 {
    for (int i=0; i<v.size(); ++i)
    {
        int(&p)[100] = v[i].b;
        for (int j=0; j<100; ++j) 
           cout <<p[j];
    }
 }
class A {};

extern "C" void f(int &i, A a) {
    i++;
}