[dcl.link] 7.5p4 に示すように、foo1 は C 関数へのポインターを受け取ります。
リンケージ仕様では、指定された言語リンケージは、すべての関数宣言子の関数型、外部リンケージを持つ関数名、およびリンケージ仕様内で宣言された外部リンケージを持つ変数名に適用されます。[例:
extern "C" void f1(void(*pf)(int));
// f1 という名前とその関数型には C 言語の
// リンケージがあります。pf は C 関数へのポインタです
この例は直接適用されfoo1
、追加された強調は、私がその理由であると考えるものを強調しています. 関数のパラメーター リストにはパラメーターの関数宣言子が含まれており、すべての関数宣言子はリンケージ仕様の影響を受けます。これは、ブレース付きおよびブレースなしのリンケージ仕様の両方に適用されます。
中括弧を使用しない場合のいくつかの違いは、名前が自動的extern
に指定され、ストレージ指定子の明示的な使用が禁止されていることです。
extern "C" int i; // not a definition
int main() {
i = 1; // error, no definition
}
extern "C" static void g(); // error
この違いが問題となる例として、以下を含むヘッダーを考えてみましょう。
extern "C" int a;
extern "C" double b;
extern "C" char c;
誰かがこれを次のように変更したくなるかもしれません:
extern "C" {
int a;
double b;
char c;
}
しかし、それは宣言を定義に変換するため、正しくありません。代わりに、使用する正しいコードextern "C" {}
は次のとおりです。
extern "C" {
extern int a;
extern double b;
extern char c;
}