【问题标题】:C preproccessor problemC预处理器问题
【发布时间】:2011-07-19 14:59:17
【问题描述】:

我有一个程序来查找数字的倒数,但主程序是用 C 编写的,reciprocal 函数是用 C++ 编写的。接下来我有一个头文件 reciprocal.hpp,其中包含一些条件编译代码这使得reciprocal 函数成为外部函数。有人可以解释一下reciprocal.hpp 程序中有什么。

ma​​in.c

#include<stdio.h>
#include<stdlib.h>

int main(int argc,char **argv)
{
int i;
i = atoi(argv[1]);
printf("\nThe reciprocal of %d is %f\n",i,reciprocal(i));
return 0;
}

reciprocal.cpp

#include<cassert>
#include "reciprocal.hpp"

double reciprocal(int i)
{
assert( i != 0);
return 1.0/i;
}

reciprocal.hpp

#ifdef __cplusplus
extern "C"
{
#endif

extern double reciprocal(int i);

#ifdef __cplusplus
}
#endif

我不明白reciprocal.hpp 发生了什么。请帮忙!!

【问题讨论】:

  • 您的问题确实是关于 C++ 的。标签被替换。我相信extern "C"thingamaging 会阻止 C++ 编译器执行 name-mangling
  • extern "C" 的可能重复项
  • @interjay:不是完全重复(但很接近),因为这也涉及预处理器以及如何处理 C/C++ 之间的差异
  • @pmg:它做得更多。它强制编译器使用 C ABI。这意味着代码的生成方式存在一些差异。例如:在 C 中的堆栈上传递参数/返回值(通常)。如果编译器认为这在 C++ 中更有效(通常),则通过寄存器传递参数和返回值。在所有示例中,您的里程可能与编译器和优化设置有关。

标签: c++


【解决方案1】:

C++ 编译器总是定义__cplusplus 符号。所以,标题正在做的是将原型包装在

extern "C" { ... }

这告诉编译器不要对该块中包含的任何内容执行name mangling。现在,C 代码可以通过其原始名称来引用该函数,就好像它是一个 C 函数一样。

【讨论】:

  • 为什么需要两个#ifdef __cplusplus
  • extern "C" 声明仅适用于紧随其后的语句。要使其适用于多个语句,请将所有这些语句括在 {} 块中。第二个#ifdef 用于切换右大括号。
【解决方案2】:

如果您指的是ifdefs,如果标头编译为 C++,它们只是允许将函数导出到 C。 extern 行只是为reciprocal 定义了一个函数原型。

【讨论】:

    猜你喜欢
    • 2019-07-12
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2011-07-02
    相关资源
    最近更新 更多