[英]Why does the C++ compiler allow extern keyword combined with definition?
[英]how does extern “C” allow C++ code in a C file?
为了在C文件中使用C ++代码,我读到我们可以做extern "C" { (where the c++ code goes here)}
,但是当我尝试使用cout打印出来时,我不断收到错误,因为它无法识别图书馆。 我想我对extern“C”如何允许你在C中使用C ++代码感到困惑。
反之亦然。 您可以使用extern C使用C ++编译器添加要编译为C代码的代码。
除非我遗漏了一些东西,否则你无法使用C编译器编译C ++代码。
extern "C"
构造是一种特定于C ++的语法,没有C编译器会理解它。
这就是为什么你几乎总会看到它与一些条件编译配对
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
extern "C"
作用仅仅是禁止名称修改,这意味着C ++源文件中定义的符号可以在C程序中使用。
这允许您拥有一个具有混合C和C ++源的项目,并且C源可以调用已定义为extern "C"
的C ++函数。
非常简单,愚蠢的例子只是为了说明这一点:
假设我们有一个C源文件,用C编译器编译:
#include <stdio.h>
void foo(void); // Declare function prototype, so it can be called
int main(void)
{
printf("Calling foo...\n");
foo();
printf("Done\n");
return 0;
}
然后我们有一个foo
函数的C ++源文件:
#include <iostream>
extern "C" void foo()
{
std::cout << "Hello from foo\n";
}
C源文件使用C编译器编译,C ++源文件使用C ++编译器编译。 然后将两个目标文件链接在一起以形成可执行程序。 因为foo
被定义为extern "C"
,所以目标文件中的符号名称不会被破坏,链接器可以解析C编译器创建的目标文件中的引用。
它也适用于另一个方向。 因为C中的符号没有被破坏,所以C ++编译器需要知道这一点,并且通过使用如上所示的条件编译通常在头文件中声明C符号extern "C"
来完成。 如果未使用extern "C"
,则C ++编译器会认为符号是C ++符号,并且当链接器无法找到损坏的符号时,会破坏导致链接器问题的名称。
同样愚蠢的例子:首先是一个C ++源文件
#include <iostream>
extern "C" void bar(); // Declare function prototype as an unmangled symbol
int main()
{
std::cout << "Calling bar...\n";
bar();
}
然后是C源文件
#include <stdio.h>
void bar(void)
{
printf("Inside bar\n");
}
extern "C"
是一种将C代码放入C ++代码的方法。 更具体地说,它告诉编译器禁用某些功能,例如函数重载,这样它也可以关闭名称修改。 在C ++中,一个简单的函数如:
int add(int a, int b) {
return a+b;
}
实际上会在库中获得一些时髦的名称来表示参数,这样如果你定义另一个函数,如:
double add(double a, double b) {
return a+b;
}
它知道要拨打哪一个。 如果您正在尝试使用C库,那么您不希望这样,那就是extern "C"
的用途。 所有这些都说, extern "C"
不允许在C程序中使用C ++。
导出的C ++符号(由编译器生成) 被修改为包含有关符号的其他类型信息到链接器。
因此,C ++中的链接器可以区分以下重载函数,但不能区分C:
int fn();
int fn(int);
int fn(char*);
int fn(char*) const;
int fn(const char*);
extern "C" {
... }
语法允许在C ++代码中定义符号(或对C符号的引用),而不使用mangling
规则。 这允许这样的C ++代码与C库链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.