使用extern"C"时是否有大括号或没有大括号?

jxh*_*jxh 14 c++

因此,在接受James Kanze和Loki Astari关于C联动的培训时,我对此感到疑惑:

extern "C" int foo1 (void (*)());
extern "C" { int foo2 (void (*)()); }
Run Code Online (Sandbox Code Playgroud)

在我上学之后,我认为必须foo1只使用带有C++链接foo2的函数指针,而只需要带有C链接的函数指针.我的理解是否正确?C++标准中是否有特定的参考资料来解释上述示例中的差异?

编辑:为了让每个人都能更方便地遵循这里的一个带有C++ 11草案标准相关部分的pastebin.

bam*_*s53 9

foo1接受一个指向C函数的指针,如[dcl.link] 7.5p4所示

链接规范中,指定的语言链接适用于所有函数声明符的函数类型,具有外部链接的函数名称,以及在链接规范中声明的具有外部链接的变量名称.[例:

extern "C" void f1(void(*pf)(int));
                                                                 //名称f1及其函数类型具有C语言
                                                                 //链接; pf是指向C函数的指针

这个例子直接适用foo1于增加的重点突出了我认为的原因.函数的参数列表包含参数的函数声明符,并且所有函数声明符都受链接规范的影响.这适用于支撑和非支撑连杆规格.

不使用大括号时的一些差异是名称是自动的,extern并且禁止显式使用存储说明符.

extern "C" int i; // not a definition

int main() {
    i = 1; // error, no definition
}

extern "C" static void g(); // error
Run Code Online (Sandbox Code Playgroud)

作为这种差异的重要示例,请考虑包含以下内容的标头:

extern "C" int a;
extern "C" double b;
extern "C" char c;
Run Code Online (Sandbox Code Playgroud)

有人可能会想要将其更改为:

extern "C" {
    int a;
    double b;
    char c;
}
Run Code Online (Sandbox Code Playgroud)

但这是不正确的,因为它将声明转换为定义.相反,正确的代码使用extern "C" {}是:

extern "C" {
    extern int a;
    extern double b;
    extern char c;
}
Run Code Online (Sandbox Code Playgroud)