我遇到了一段正在工作的代码(使用XLC8和MSFT9编译器),其中包含一个带有C链接和引用参数定义函数的C++文件。这让我很困扰,因为引用仅限于C++。所讨论的函数是从C代码调用的,在C代码中,函数被声明为接受指向同一类型的指针参数,而不是引用参数。
简化示例
C++文件
extern "C" void f(int &i)
{
i++;
}
C文件
void f(int *);
int main()
{
int a = 2;
f(&a);
printf("%d\n", a); /* Prints 3 */
}
现在,街道上的单词是,大多数C++编译器在幕后实现引用,就像一个指针。它是这样的,只是纯粹的运气,这是这段代码工作的原因,还是它在C++规范的某个地方说,当您定义一个带有引用参数和C链接的函数时,结果是什么?我没能找到这方面的任何信息。
发布于 2009-12-15 01:13:40
我的n3000.pdf副本(来自这里),在7.5-Linkage规范中有这样的说明。
9.从C++到用其他语言定义的对象和从其他语言定义的C++对象之间的链接是实现定义的和语言依赖的。只有在两种语言实现的对象布局策略足够相似的情况下,才能实现这种链接。
因为C和C++是不同的语言,这意味着您不能依赖普通编译器的“特性”。
较强的是同一节中的附注5(重点是地雷):
如果两个声明将具有相同名称和参数类型列表(8.3.5)的函数声明为同一命名空间的成员,或将同名的对象声明为同一命名空间的成员,并且声明给出了不同的语言链接,则程序的格式不正确;如果声明出现在不同的翻译单元中,则不需要进行诊断。
因此,我要说的是,您所做的并不能保证按照标准工作,编译器也不需要为您给出的示例打印诊断,因为声明位于不同的翻译单元中。
FYI,它“为我工作”与gcc和g++版本4.2.1雪豹。
发布于 2009-12-15 00:58:56
在许多情况下,但不是所有情况下,引用都可以用“自动取消引用”指针来实现。在C++标准中,任何特定的编译器都不能以这种方式处理具有C链接和引用参数的函数,因此您应该将其视为实现细节。
如果您需要在不依赖实现细节的情况下这样做,编写一个接受指针并调用函数的转发函数并不困难:
void real_f(int& n) {
n++;
}
extern "C" void f(int* p) { // called from C code
real_f(*p);
}
发布于 2009-12-15 01:03:27
引用是对象的备用名称。从技术上讲,C中没有任何东西可以直接映射到C++引用。
引用的明显实现是(常量)指针,每次使用它时都取消引用。因此,根据编译器实现引用的方式,代码可能会工作。但这是不对的。
解决方案是编写一个C函数,它接收一个真实的对象或指向该对象的指针,然后从该对象调用C++函数。
https://stackoverflow.com/questions/1906000
复制相似问题