C++ by-reference参数和C链接

olo*_*ovb 13 c c++ compiler-construction pointers reference

我遇到了一段代码(包含XLC8和MSFT9编译器),包含一个带有C链接和引用参数定义的函数的C++文件.这让我很烦,因为引用只是C++.有问题的函数是从C代码调用的,它被声明为将指针参数取代到相同的类型而不是引用参数.

简化示例:

C++文件:

extern "C" void f(int &i)
{
    i++;
}
Run Code Online (Sandbox Code Playgroud)

C档案:

void f(int *);

int main()
{
    int a = 2;
    f(&a);
    printf("%d\n", a);  /* Prints 3 */
}
Run Code Online (Sandbox Code Playgroud)

现在,街上的一句话就是大多数C++编译器,它们都像指针一样实现引用.是这样的,只是纯粹的运气,这个代码工作的原因,或者说它在C++规范中的某处说明当你用引用参数和C链接定义一个函数时的结果是什么?我无法找到任何相关信息.

小智 11

在许多情况下,但不是全部,可以使用"自动解除引用"指针实现引用.在C++标准中,任何特定的编译器都不会以这种方式处理具有C链接和引用参数的函数,您应该将其视为实现细节.

编写一个带指针并调用函数的转发函数并不难,如果你需要这样做而不依赖于实现细节:

void real_f(int& n) {
  n++;
}
extern "C" void f(int* p) { // called from C code
  real_f(*p);
}
Run Code Online (Sandbox Code Playgroud)


Alo*_*hal 5

我的副本n3000.pdf(从这里开始),在7.5 节 - 链接规范中有这个说法:

9.从C++到在其他语言中定义的对象以及从其他语言在C++中定义的对象的链接是实现定义的和语言相关的.只有在两种语言实现的对象布局策略足够相似的情况下才能实现这种联系.

由于C和C++是不同的语言,这意味着你不能依赖常见编译器的这个"特性".

强调是同一部分中的注释5(强调我的):

如果两个声明声明具有相同名称的函数,并且参数类型列表(8.3.5)是同一命名空间的成员,或者声明具有相同名称的对象是同一命名空间的成员,并且声明为这些名称提供不同的语言链接,该计划是不正常的; 如果声明出现在不同的翻译单元中,则无需诊断.

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

仅供参考,在Snow Leopard上使用gcc和g ++版本4.2.1"对我有用".

  • 在这种情况下,我认为标准非常清楚,所以如果更改代码很容易,你应该这样做. (2认同)