为什么要使用extern "C"

C/C++中extern C的作用

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C/C++采用的是分别编译模型, 源代码只要声明函数, 就可调用。

编译时,在函数调用处生成一个符号引用。

链接时,将函数调用处的符号引用,替换成地址(甚至仍有可能继续保留符号, 载入时再计算地址)。

所以, 以下两者必须完全比配, 否则链接时会出错。

1. 函数调用处引用的符号名

2. 函数定义处公开的符号名

如何使得两者匹配?

无论是在调用处还是在定义处, 无论是C还是C++(注1), 编译器都会对函数名进行mangling, 产生一个符号名。

而 extern "C" 就是通知C++编译器(注2), 将某函数按照C的规则进行mangling, 产生符号名。

如果是在声明处使用 extern "C", 函数调用处引用的符号名将按C的mangling规则产生。

如果是在定义处使用 extern "C", 翻译单元里公开的符号名将按C的mangling规则产生。

同时, C编译器将 extern "C" 视为错误—— 所以需要类似的代码

#ifdef __cplusplus
extern "C" {
#endif 

/*...*/ 

#ifdef __cplusplus
}
#endif

extern "C" 通常使用的地方。

1. 当一个函数已经由C编译器实现

在一个C++翻译单元中, 必须使用 extern "C" 声明改函数。

这样, 该函数调用产生的符号名引用和已经由C编译器实现的函数的符号名才能匹配。

2. 用C++编译器实现C和C++都可调用的函数。

自己声明extern “C”。 在C++翻译单元中, 该函数名按C规则修饰之后, 得到符号名, 并公开。

C++的调用者依然需要使用 extern "C" 来声明。

C的调用者直接声明。

目的也是为了使得引用与实现的符号名匹配。


转载于:https://my.oschina.net/xlplbo/blog/330593

<think>好的,我现在需要回答用户的问题:“为什么有些函数前面要用extern”。首先,我要确保自己正确理解extern关键字的用途,尤其是在函数声明中的使用场景。 首先,extern在C和C++中用于声明变量或函数的外部链接性。对于函数来说,默认情况下,函数的声明是带有外部链接的,这意味着即使不使用extern,函数也可以在别的文件中访问。不过,有时候显式地使用extern可以增加代码的可读性,明确表明该函数是在其他文件中定义的。 接下来,我需要考虑不同情况下的使用场景。比如,在头文件中声明函数时,通常会加上extern,虽然这可能不是必须的,但有助于表明该函数是在其他地方实现的。另外,在C++中,当需要与C代码进行链接时,会使用extern "C"来避免名称修饰,确保函数名正确链接。 然后,我应该区分变量和函数在extern使用上的不同。对于变量,extern是必须的,如果要在多个文件中共享全局变量,需要在头文件中用extern声明,在源文件中定义。而函数由于默认外部链接,通常不需要,但显式使用可能有助于代码清晰。 还要注意,用户可能对extern的具体语法和实际应用场景有疑问。例如,在多个文件项目中,如何正确使用extern来声明和定义函数,避免重复定义错误。同时,可能需要解释链接器的角色,以及extern如何影响链接过程。 最后,需要确保回答结构清晰,分点说明,使用例子帮助理解,同时遵循用户要求的格式,如使用中文、避免Markdown,正确应用数学公式的格式(虽然这个问题可能不涉及数学公式,但需注意系统指令)。检查是否有错误或遗漏的部分,确保信息准确。</think>在C/C++语言中,`extern`关键字用于声明变量或函数的外部链接性。对于函数声明来说,使用`extern`的主要作用有: 1. **显式声明外部链接** - 默认情况下函数声明自带`extern`属性 - 例如: ```c extern void printMessage(); // 显式声明 void printMessage(); // 隐式带有extern ``` - 这两种声明方式在功能上是等价的 2. **跨文件访问函数** - 当函数定义在一个源文件(.c/.cpp)中,要在其他文件中使用时: ```c // file1.c void showData() { /* 实现 */ } // file2.c extern void showData(); // 声明外部函数 ``` 3. **C++与C混合编程** - 在C++中调用C编译的函数时需要: ```cpp extern "C" { void c_function(); // 禁止C++的名称修饰(name mangling) } ``` - 确保链接器能找到正确的符号 4. **头文件中的最佳实践** - 在头文件中推荐显式使用`extern`: ```c // mylib.h extern void initSystem(); // 明确表示实现在其他位置 ``` 5. **与变量的区别** - 变量声明必须显式使用`extern`: ```c extern int globalCount; // 声明 // 某处需要定义:int globalCount = 0; ``` 注意特殊情况: - 当使用`static`修饰函数时,表示内部链接(仅本文件可见) - C++中`extern template`用于显式实例化声明 总结:函数前的`extern`主要起文档说明作用,实际开发中常被省略。但显式使用可以提高代码可读性,明确表示函数实现在其他位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值