16

extern "C" {}C++プログラムに標準のCヘッダーを含めるためのブロックが必要ですか。C++に対応するものがない標準のCヘッダーのみを検討してください。

例えば:

extern "C" {
 #include <fcntl.h>
 #include <unistd.h>
}
4

6 に答える 6

21

システム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
于 2011-11-10T22:56:06.370 に答える
10

<fcntl.h>C++ でのとの動作は<unistd.h>、標準では指定されていません (これらも C89 標準の一部ではないため)。そうは言っても、(a) 存在し、(b) 実際にextern "C"ブロックにラップする必要があるプラットフォームを見たことがありません。

<stdio.h><math.h>、およびその他の標準 C ヘッダーの動作は、C++03 標準のセクション D.5 で指定されています。それらはラッパー ブロックを必要とせずextern "C"、シンボルをグローバル名前空間にダンプします。ただし、附属書 D のすべては「非推奨」です。

これらのヘッダーの正規の C++ 形式は<cstdio><cmath>などであり、C++ 標準のセクション 17.4.1.2 (3) で指定されています。

<cassert> <ciso646> <csetjmp> <cstdio> <ctime> <cctype> <climits>
<csignal> <cstdlib> <cwchar> <cerrno> <clocale> <cstdarg> <cstring>
<cwctype>

条項 18 から 27 に記載されている場合を除き、各ヘッダー cname の内容は、ISO/IEC 9899:1990 プログラミング言語 C (条項 7) または ISO/IEC で指定されているように、対応するヘッダー name.h の内容と同じでなければなりません。 :1990 プログラミング言語 — 修正条項 1: C の整合性 (第 7 条)、必要に応じて、包含によるかのように。ただし、C++ 標準ライブラリでは、宣言と定義 (C でマクロとして定義される名前を除く) は名前空間 std の名前空間スコープ (3.3.5) 内にあります。

printfしたがって、 C++ で(たとえば) を使用する標準的で非推奨の標準的な方法は#include <cstdio>、 を呼び出してから呼び出すことstd::printfです。

于 2011-11-10T23:00:48.597 に答える
2

そうです。ただし、多くのシステム(特にLinux)は、extern "C"あなたと同じようにすでにブラケットを追加しています。(Linuxの場合)ファイルと、多くのLinuxシステムのインクルードファイルで定義および使用され/usr/include/unistd.h /usr/include/features.hているマクロ を参照してください。__BEGIN_DECLS/usr/include/sys/cdefs.h

したがって、Linuxでは、通常は回避できますextern "C"が、害はありません(そして、私見では、その場合は読みやすさが向上します)。

于 2011-11-10T22:54:47.910 に答える
1

いいえ、C++ ラッパー ヘッダーを使用する必要があります (たとえば、 など<cstdio>)。それらはすべてあなたのために世話をします。

それらを持たないヘッダーの場合は、はい、それらを でラップする必要がありますextern "C" {}

ETA:多くの実装では、以下のように .h ファイル内にラッパーが含まれていることに注意してください。これにより、自分で実行しなくても済むようになります。

#ifdef  __cplusplus
extern "C" {
#endif

#ifdef  __cplusplus
}
#endif
于 2011-11-10T22:51:12.657 に答える
-1

I just double checked the stdlib.h for the GNU compiler and the declarations do not use extern "C" as declarations.

edit:

if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES
define __BEGIN_NAMESPACE_STD    namespace std {

So including the old headers will place declarations on std provided _GLIBCPP_USE_NAMESPACES is defined?

于 2011-11-10T22:58:23.343 に答える
-1

C++ としてコンパイルするときに C コードを予期できるように、コンパイラに通知することをお勧めしますextern "C" {ヘッダー ファイル自体にガードとして含まれている場合もあります。

たとえば、curses.h私のシステムには次のものが含まれています。

#ifdef __cplusplus
extern "C" {
...
于 2011-11-10T22:53:31.500 に答える