C/C++檔案語法區分+__cplusplus

wenli7363發表於2024-07-19

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

相關文章