C/C++文件语法区分+__cplusplus
0 前言
我经常把C/C++混淆在一起用,所以经常很晕。比如一个场见的bug:C语言程序使用<string.h>头文件中的memset时没问题,但是C++中使用有时候会出错,链接器会报错找不到memset这个函数。
原因是C++的编译器为了支持重载这个特性,会对函数进行修饰,所以memset编译后会改成
_Z6memsetPvii
(不同编译器的符号修饰过程不同),所以C++链接器是找不到这个函数的。而C语言中没有问题,是因为c语言编译器的并没有符号修饰这种东西。
最常见的做法是添加extern "C"
声明,告诉编译器这段代码不要用符号修饰,按照C语言的方式编译。
1 __cplusplus宏定义
这个是一个预定义的宏,用于指示编译器正在编译C++代码,并且其值代表了所使用的C++标准的版本。这个宏在所有C++编译器中都是自动定义的。
// 当c++代码的时候,会自动加上extern,但是C语言的时候就不会加上。
#ifdef __cplusplus
extern "C" {
#endif
void exampleFunction();
#ifdef __cplusplus
}
#endif
用__cplusplus进行不同cpp版本声明
== __cplusplus 的值==
- 在C++98中,__cplusplus的值是199711L。
- 在C++11中,__cplusplus的值是201103L。
- 在C++14中,__cplusplus的值是201402L。
- 在C++17中,__cplusplus的值是201703L。
- 在C++20中,__cplusplus的值是202002L。
看这个复杂的例子
#ifdef __cplusplus
#if __cplusplus >= 201103L
// C++11及以上标准的代码
#include <thread>
void newFeature() {
std::thread t([] { /* ... */ });
t.join();
}
#else
// C++11之前标准的代码
void oldFeature() {
// ...
}
#endif
#endif