为什么要使用“ extern“ C ++””?


Answers:


106

语言允许:

extern "C" {
  #include "foo.h"
}

如果foo.h包含需要C ++链接的内容怎么办?

    void f_plain(const char *);
    extern "C++" void f_fancy(const std::string &);

这就是使链接器保持快乐的方式。


3
我不明白反对票。这是一个需要extern C ++的用例,并且是合法的。
Thomas L Holaday

1
我也不明白。这是extern“ C ++”的有效用法
Johannes Schaub-litb

3
它不仅有效,而且我已经在野外使用它(这是我的“ aha”时刻)。看看winnt.h。
Michael Burr

不用担心 我之所以投票赞成,是因为我原本没有投票赞成票。不是因为它不值得投票,而是因为我本来不会想到。
flarn2006

32

没有真正的理由使用extern "C++"。它只是使链接明确,即隐式默认。如果您的班级中有些成员具有外部“ C”链接,则可能希望明确声明其他成员是外部“ C ++”。

请注意,C ++标准在语法上进行了定义extern "anystring"。它只给正规的含义extern "C"extern "C++"。编译器供应商可以自由定义extern "Pascal"或随意定义extern "COM+"


这确实是问题的完美答案。如果可以的话,我会投更多票。
Randolpho

4
当您需要覆盖周围范围中的其他一些链接规范时,可以使用它。
Thomas L Holaday

7
希望编译器受支持extern "Haskell"

20

我不确定为什么需要这样做,但是根据Sun的这篇文章,您可以在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
}

这可能是为了处理在extern节之一中包含标头的情况。
ThomasW 2011年

6

两个猜测:

  • 如果您位于某个extern "C"块中,则可以通过指定nested重新获得C ++语言链接extern "C++"
  • 它保留了C++链接,因为它是定义C ++的文档。谁在定义C++语言链接方面比其本身更合适。它还提供了完整性。与相同signed/unsigned

阅读此答案也可以解释extern "LanguageName"(即GCC拥有extern "Java")。



2

C和C ++使用不同的名称处理规则。本质上,extern“ C”告诉C ++编译器将函数命名为C。


1
实际上,名称修饰纯粹是一个实现细节。语言本身根本没有任何混乱的“规则”。各种编译器以不同的方式处理函数重载。名称修饰只是一种流行的方法。
James Curran

1

这指定要使用的链接约定。大多数语言都知道如何与“ C”样式函数链接。

在两种情况下,您需要这样做:

  • AC-或其他相关语言-程序调用用C ++编写的函数
  • 调用用C编写的函数的C ++程序

范例:

// declared in function.h
void f1(void);

您的C代码(实际上其他语言也可以与C函数链接)将无法与其链接,因为对象表中的名称将使用C ++约定。

如果你写

extern "C" void f1(void);

现在,链接有效,因为它使用C约定。


1

我使用extern“ C”的#1原因是为了避免C ++的名称修改规则。如果您使用的是.Net语言,并且希望PInvoke进入特定的本机函数,那么这非常重要。唯一的方法是禁用名称改写。


-1

简短的答案是,您可以使用extern C告诉编译器不要使用名称修饰。这意味着您可以将同一项目中的C和C ++代码的各个部分链接在一起。


但是,问题主体也提出了詹姆斯回答的问题。
Dominic Rodger

1
extern“ c”很容易被谷歌搜索,但是extern“ c ++”是一个有趣的问题,如果我错了,将把它收回!
保罗·迪克森

在我看来,这是您为什么要使用两者之一的问题。现在有更好的答案,所以没关系。
詹姆斯·布鲁克斯

-2

extern“ C”用来表示C ++函数应具有C链接。这意味着依赖于实现,但是通常它会关闭C ++名称处理(以及重载和严格的类型检查)。当您具有要从C代码调用的C ++函数时,可以使用它:

extern "C" void Foo();   // can be called easily from C

至于外部的“ C ++”,尽管C ++ Standard允许它,但我从未在实际代码中看到它。我猜这是没有操作的。


1
实际上,它主要用于相反的操作:从C ++代码调用C函数。如果您调用printfC ++代码,则链接需要知道它在库中,printf而不是在库中printf_#$D%G^_&_^
James Curran 2009年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.