我是否需要一個extern "C" {}
塊來在C++程序中包含標準C頭文件。只考慮在C++中沒有對應的標準C頭文件。我是否需要一個外部「C」塊來包含標準C頭文件?
例如:
extern "C" {
#include <fcntl.h>
#include <unistd.h>
}
我是否需要一個extern "C" {}
塊來在C++程序中包含標準C頭文件。只考慮在C++中沒有對應的標準C頭文件。我是否需要一個外部「C」塊來包含標準C頭文件?
例如:
extern "C" {
#include <fcntl.h>
#include <unistd.h>
}
C++中的<fcntl.h>
和<unistd.h>
的行爲未由標準規定(因爲它們也不是C89標準的一部分)。也就是說,我從來沒有見過他們(a)存在的平臺和(b)實際需要被包裹在extern "C"
區塊中的平臺。
<stdio.h>
,<math.h>
的行爲,其他標準C標頭由C++ 03標準的D.5節指定。它們不需要extern "C"
包裝程序塊,它們將它們的符號轉儲到全局名稱空間中。但是,附錄D中的所有內容都是「不推薦使用」的。
這些頭的規範C++形式是<cstdio>
,<cmath>
等,並且它們由部分17.4.1.2指定(3)C++標準,它說的:
<cassert> <ciso646> <csetjmp> <cstdio> <ctime> <cctype> <climits>
<csignal> <cstdlib> <cwchar> <cerrno> <clocale> <cstdarg> <cstring>
<cwctype>
除在第18至27條中註明,每個標題012xxcname的內容應與ISO/IEC 9899:1990編程語言C(第7章)或 中規定的 對應的標題name.h相同,即ISO/IEC:1990編程語言-C修正1:C完整性,(條款 7),如ap似乎通過包含。然而,在C++標準庫 中,聲明和定義(除了在C中定義爲宏的名稱 除外)位於名稱空間標準的名稱空間範圍(3.3.5)內。
所以標準的,非棄用,典型的方式使用(例如)在printf
C++是#include <cstdio>
,然後調用std::printf
。
不,你應該使用C++封裝報頭(例如像<cstdio>
)。那些照顧你的一切。
如果這是一個頭沒有這些,那麼是的,你會想要把它們包裝在extern "C" {}
。
ETA:值得注意的是,許多實現將在下面的.h文件中包含包裝器,這樣你就可以不用自己做。
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
值得注意的是'
這是一個好主意,讓編譯器知道,以便它可以作爲C++編譯時預計的C代碼。你也可能會發現頭文件本身包含extern "C" {
作爲守衛。
例如,curses.h
我的系統上載:
#ifdef __cplusplus
extern "C" {
...
*「讓編譯器知道,以便在編譯爲C++時能夠期待C代碼」* - 這不是什麼'extern「 C「'做。它不會改變代碼的解釋。它甚至不適用於代碼。它是一種語言鏈接指令,它指示編譯器生成符合鏈接器對C語言要求的符號。它使C++代碼可以從C中調用,但不會更改代碼生成。 – IInspectable
@IInspectable不是_「指示編譯器生成與鏈接器期望的符號兼容的符號」_暗示它適用於代碼,或者至少是代碼的調用約定?它肯定會讓編譯器(以及連接器)知道一些東西。 – Tanz87
@ Tanz87:它不會改變代碼的生成。生成的目標代碼與「extern」C「'是否相同。該指令僅適用於符號命名。它對調用約定沒有影響。 – IInspectable
是的,你做的。然而,許多系統(特別是Linux)已經像你一樣增加了一個extern "C"
包圍。請參閱(在Linux上)文件/usr/include/unistd.h
/usr/include/features.h
和在/usr/include/sys/cdefs.h
中定義的宏__BEGIN_DECLS
,並在許多Linux系統包含文件中使用。
所以在Linux上,你通常可以避免你的extern "C"
,但它不會損害(並且,恕我直言,在這種情況下提高可讀性)。
系統C頭通常包含一個extern "C"
塊,由#ifdef __cplusplus
保護。這樣,當編譯爲C++時,函數會自動聲明爲extern "C"
,並且您不需要手動執行該操作。
例如我的系統unistd.h
上fcntl.h
開始與__BEGIN_DECLS
與__END_DECLS
結束,這是在sys/cdefs.h
定義的宏:
/* C++ needs to know that types and declarations are C, not C++. */
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
在我看來它的出口頭文件的責任,用外部的「C 「適當。
我剛剛檢查了GNU編譯器的stdlib.h,聲明不使用extern「C」作爲聲明。
編輯:
if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES
define __BEGIN_NAMESPACE_STD namespace std {
所以包括舊標題將放在STD提供_GLIBCPP_USE_NAMESPACES聲明定義?
剛剛發現這個問題與您的問題類似:[爲什麼我們需要在C++中使用extern「C」{#include}?](http://stackoverflow.com/questions/67894/why-do-we-need -extern -c-include-foo-h-in-c) –
AusCBloke