在此article中,关键字extern后面可以跟“C”或“C ++”。为什么要使用'extern'C ++“'?这是否实用?
答案 0 :(得分:99)
语言允许:
extern "C" {
#include "foo.h"
}
如果foo.h包含需要C ++链接的内容怎么办?
void f_plain(const char *);
extern "C++" void f_fancy(const std::string &);
这就是你如何保持链接器的快乐。
答案 1 :(得分:32)
没有真正的理由使用extern "C++"
。它只是明确了隐式默认的链接。如果你有一个类,其中一些成员有外部“C”链接,你可能希望明确说明其他成员是外部“C ++”。
请注意,C ++标准在语法上定义extern "anystring"
。它只给出extern "C"
和extern "C++"
的正式含义。如果他们愿意,编译器供应商可以自由定义extern "Pascal"
甚至extern "COM+"
。
答案 2 :(得分:18)
我不确定你为什么需要这样做,但是根据Sun的this文章,你可以在extern“C”块中使用extern“C ++”来指定组中的某些函数“C”函数具有本机C ++链接。
extern "C" {
void f(); // C linkage
extern "C++" {
void g(); // C++ linkage
extern "C" void h(); // C linkage
void g2(); // C++ linkage
}
extern "C++" void k();// C++ linkage
void m(); // C linkage
}
答案 3 :(得分:6)
两个猜测:
extern "C"
块中,则可以通过指定嵌套extern "C++"
来再次获得C ++语言链接。C++
链接,因为它是定义C ++的文档。谁能更好地定义C++
语言链接而不是它本身。它还提供完整性。与signed/unsigned
相同的交易。 阅读解释extern "LanguageName"
的{{3}}(即GCC有extern "Java"
)。
答案 4 :(得分:3)
外部“C”被许多人回答。 extern“C ++”的用例是在C函数中调用C ++库函数时。相关的子用例是将C ++库与带有main函数的C源代码链接起来。请查看此wiki page了解详情:
答案 5 :(得分:2)
C和C ++使用不同的name mangling rules。本质上,extern“C”告诉C ++编译器将函数命名为C命名它。
答案 6 :(得分:1)
指定要使用的链接约定。大多数语言都知道如何与“C”风格函数链接。
在两种情况下你需要这个:
示例:
// declared in function.h
void f1(void);
您的C代码 - 实际上其他语言能够与C函数链接 - 将无法链接到它,因为对象表中的名称将使用C ++约定。
如果你写
extern "C" void f1(void);
现在链接有效,因为它使用C约定。
答案 7 :(得分:1)
我使用extern“C”的第一个原因是避免使用C ++的名称修改规则。如果您使用.Net语言并希望将PInvoke转换为特定的本机函数,这一点非常重要。唯一的方法是禁用名称修改。
答案 8 :(得分:0)
回答第二个问题,“它实用吗?”:
在像 <cmath>
这样的标准标头中,这是实用的,而且几乎是不可避免的。
想象一个只有头文件的库 X.h,它是用 C++ 和 C 的一个公共子集编写的,并且打算在两种语言中使用。为了 C++ 用户的利益,X.h 包含 <cmath>
,而不是 <math.h>
。但是,这对 C 用户不起作用,如果 <cmath>
的作者没有将所有内容都夹在 extern "C++" {
... }
中。
答案 9 :(得分:-1)
简短的回答是你可以使用extern C告诉编译器不要使用名称修改。这意味着您可以将同一项目中的C和C ++代码链接在一起。
答案 10 :(得分:-2)
extern“C”用于表示C ++函数应该具有C链接。这意味着依赖于实现,但通常会关闭C ++名称修改(以及重载和严格类型检查)。当你想要从C代码调用C ++函数时使用它:
extern "C" void Foo(); // can be called easily from C
至于extern“C ++”,我从未在实际代码中看到它,尽管C ++标准允许它。我想这是一个无操作。