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