*.h
ライブラリのヘッダーファイルで、関数C
を宣言する必要があります
extern void f();
// or only
void f();
- でのみ使用する場合
C
- から使用する場合
C++
。
extern
CまたはC++のいずれかで関数を宣言するときに、キーワードを使用する必要は[ほとんど]ありません。CおよびC++では、すべての関数にデフォルトで外部リンケージがあります。ヘッダーファイルで関数を宣言するという奇妙な習慣には、extern
おそらくいくつかの歴史的なルーツがありますが、それはすでに何十年もの間完全に無関係です。
上記のCには、上記の1つの[あいまいな?]例外があります。これは、おそらくあなたが質問していることに直接関係していません。C言語(C99)で、ある翻訳単位で関数が次のように定義され、次のようinline
に宣言されている場合extern
(明示的extern
な使用)その場合、その関数のインライン定義は外部定義としても機能します。明示的な宣言がextern
変換ユニットに存在しない場合、インライン定義は「内部」定義としてのみ使用されます。
PS C ++のようなものがありますextern "C"
が、それはまったく別の問題です。
Cライブラリのヘッダーファイルで、関数を宣言する必要があります。
extern void f(); // or only void f();
C ++プログラムでは、関数は値を返さず、引数をとらない関数として宣言されます。
Cプログラムでは、関数は値を返さず、不定であるが可変長の引数のリストをとらない関数として宣言されます。
Cで「引数なし」の意味を取得するには、次のいずれかを使用します。
extern void f(void);
void f(void);
同じ表記法は、C ++でも同じことを意味しますが、純粋なC ++コードの場合void
、引数リストでの使用は慣用的ではありません(純粋なC ++コードでは使用しないでください)。
トリッキーですが、通常のルールでは、関数をC++コードに対して。として宣言する必要がありますextern "C"
。__cplusplus
両方に同じソースコードを使用するには、マクロをテストする必要があります。通常、次のようなことを行います。
#ifdef __cplusplus
#define EXTERN_C extern "C"
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C /* Nothing */
#define EXTERN_C_BEGIN /* Nothing */
#define EXTERN_C_END /* Nothing */
#endif
EXTERN_C void f(void);
EXTERN_C_BEGIN
void f(void);
int g(int);
EXTERN_C_END
オプションとバリエーションは多岐にわたりますが、ヘッダーはCとC++の両方で使用できます。
マクロは通常、あらゆる場所で使用される1つの汎用ヘッダーで定義されます。次に、特定のヘッダーによって、汎用ヘッダーが確実に含まれ、適切な形式のマクロが使用されます。
extern
正式には、関数宣言の前に表記する必要はありません。ただし、これは外部で定義された関数の宣言であることを強調するために、またヘッダーでグローバル変数が宣言されている場合の(まれな)場合との対称性のために、ヘッダーで使用します。
人々はこれについて意見を異にすることができますし、そうします。私はローカルルールを使用しますが、ルール作成者の場合、extern
はヘッダーに含まれています。
一般的な使用のために次のように宣言します
#ifdef __cplusplus
extern "C" {
#endif
void f(void);
#ifdef __cplusplus
}
#endif
それ以外の場合extern
は、廃止されます。
後者は完全に問題ありません。これは、このヘッダーを含む関数の定義にすぎないためです。「このプロトタイプの関数がこのあたりにあります」
この文脈では、関数は変数とは明らかに異なりますが、それは別の問題です。ただし、関数本体を「インライン」またはクラス定義の一部(C ++)または「テンプレート関数」(C ++)として宣言しない限り、関数本体を含めないようにしてください。
関数プロトタイプでexternを指定しても、デフォルトで想定されているため、効果はありません。コンパイラがプロトタイプを見るときはいつでも、関数がどこか別の場所(現在または別の変換ユニット内)で定義されていると想定します。これは両方の言語に当てはまります。
次のスレッドには、externに関する一般的な有用なコメントがいくつかあります。