语言链接

来自cppreference.com
< cpp‎ | language

提供以不同程序语言书写的模块间的链接。

extern string-literal { declaration-seq(可选) } (1)
extern string-literal declaration (2)
1) 应用语言指定 string-literal 到声明于 declaration-seq 中的所有拥有外部链接的函数类型、函数名和变量
2) 应用语言指定 string-literal 到单一声明或定义。
string-literal - 要求的语言链接名称
declaration-seq - 声明的序列,可以包含嵌套的链接指定
declaration - 一个声明

目录

[编辑] 解释

所有函数类型,所有拥有外部链接的函数名,及所有拥有外部链接的变量名,拥有称作语言链接的属性。语言链接封装与以另一程序语言书写的模块链接的要求集合:调用约定名称重整算法等。

仅保证支持二种语言链接:

1) "C++",默认语言链接。
2) "C",令链接以 C 程序语言书写的函数可行,并在 C++ 程序中定义能从 C 模块调用的函数。
extern "C" {
    int open(const char *pathname, int flags); // C 函数声明
}
 
int main()
{
    int fd = open("test.txt", 0); // 从 C++ 程序调用 C 函数
}
 
// 此 C++ 函数能从 C 代码调用
extern "C" void handler(int) {
    std::cout << "Callback invoked\n"; // 它能使用 C++
}

因为语言链接是每个函数类型的一部分,故指向函数的指针也要维持语言链接。函数类型的语言链接(它表示调用约定)和函数名的语言链接(它表示名称重整)是彼此独立的:

extern "C" void f1(void(*pf)()); // 声明一个拥有 C 链接的函数 f1 ,
                             // 它返回 void 并接受指向返回 void 并不使用参数的 C 函数的指针
extern "C" typedef void FUNC(); // 声明 FUNC 为返回 void 并不使用参数的 C 函数类型
FUNC f2;            // 名称 f2 拥有 C++ 链接,但其类型是 C 函数
extern "C" FUNC f3; // 名称 f3 拥有 C 链接且其类型是 C 函数 void(void)
void (*pf2)(FUNC*); // 名称 pf2 拥有 C++ 链接,且其类型是“指向返回 void 并接受
                    // 一个‘指向返回 void 并不接受参数的 C 函数的指针’类型参数的 C++ 函数的指针”
extern "C" {
    static void f4(); // 函数 f4 的名称拥有内部链接(无语言)
                      // 但函数的类型拥有 C 语言链接
}

在同一命名空间中拥有同名和同参数列表的函数不能拥有二个不同的语言链接(注意,然而参数的链接可容许这种重载,例如 std::qsortstd::bsearch 的情况)。类似地,同一命名空间中的二个变量不能拥有二种不同的语言链接。

[编辑] "C" 链接的特殊规则

1) 当类成员声明和成员函数类型声明出现于 "C" 语言块中时,其链接仍保留 "C++"
2) 当二个拥有同一无限定名称的函数声明于不同命名空间,且都拥有 "C" 语言链接时,两个声明表示同一函数
3) 当二个拥有 "C" 语言链接和相同名称的变量出现于不同命名空间时,它们表示同一变量。
4) 一个 "C" 变量和 "C" 函数不能拥有相同名称,无关乎它们定义于同一或不同命名空间。

[编辑] 注意

语言链接只能出现在命名空间作用域

语言指定的花括号不建立作用域。

当语言指定嵌套时,有效的是最内层的指定。

函数可在带语言指定地声明后,不带链接指定地重声明,第二个声明将重使用首个语言链接。反之非真:若首个声明无语言链接,则设定其为 "C++" ,而以其他语言链接重声明是错误。

直接包含于语言链接的声明被处理为如同它含有 extern 指定符,以确定被声明名称的链接以及它是否定义

extern "C" int x; // 声明而且非定义
// 上一行等价于 extern "C" { extern int x; }
 
extern "C" { int x; } // 声明及定义

[编辑] 引用

  • C++14 standard (ISO/IEC 14882:2014):
  • 7.5 Linkage specifications [dcl.link]
  • C++11 standard (ISO/IEC 14882:2011):
  • 7.5 Linkage specifications [dcl.link]