2016-07-18 5 views
6

ははexternとスタティックについて読んだ後、私は以下の行を持っているコードに遭遇して混乱していますか?にextern「C」静的ボイド*機能

+0

好奇心:どのプラットフォームでどのコンパイラを使用しますか?関数の本体はコンパイルできないことに注意してください( 'return foo1(int * a);'は無効ですC++)。 Mac OS X 10.11.6のG ++ 6.1.0で、ソースファイル 'bust-cpp.cpp'から、コマンドラインを使ってコンパイルすると、' g ++ -O3 -g -I./inc -std = C++ 11 -Wall -wextra -Werror -c bust-cpp.cpp'メッセージを受け取ります: 'bust-cpp.cpp:1:12:error:リンク指定で' static 'を無効にしました を指す 'extern" C "static void * foo(int * a){'。 –

+0

おそらくこれは決してコンパイルされないファイルにあります –

+0

gcc-5.1はコンパイルされません(http://ideone.com/15OaqR) – PcAF

答えて

2

以下のコンパイルとはラインがやろうとしている何をするを思わ:

extern "C" { 
    static void* foo(int* a){ 
    return foo1(int* a); 
    } 
} 

私はよく分からない誰もが、しかし、これをしたいと思う理由。

"静的"とは、foo()がファイルスコープでのみ使用可能であることを意味します。

'静的な "C"は、リンカーがエクスポートされたときにリンカーによって使用される関数の名前に影響を与え、プログラム全体がリンクされているときに他のオブジェクトファイルから関数を呼び出すことができます。通常、これは、foo()が定義されているCソースからビルドされたオブジェクトファイルにリンクするか、foo()を定義したい場所にリンクして、Cのオブジェクトビルドで使用できるようにする場合に使用されます

「静的」なので、にはエクスポートされません。そのため、どちらも「助けて」いるのが分かりません。

の唯一のことは、 foo()は、テストプログラムのためにfoo()が1つのオブジェクトファイル内のfoo()の意味を上書きしようと決めた理由です別のファイルは無視されます。

+1

私はextern/static関数の理由は、Cのコールバックを望むものにポインタを渡すことだと確信しています。厳密に言えば、実際に動作していても、Cの呼び出し可能な関数を必要とするものにC++リンケージを持つ関数へのポインタを渡すことは有効ではありません。通常は普通の 'extern 'C"関数が使われますが、ポインタを必要とするだけのためにグローバル名前空間を乱雑にするのはなぜですか? –

+1

実際、C++ 11標準では、 'extern" C "{static void f4();}を使用しています。 } 'を7.5"リンケージ仕様 "の例として示しています。コメントには、「関数f4の名前には内部リンケージ(C言語リンケージではなく)があり、関数のタイプにはC言語リンケージがあります」と記載されています。 –

+0

"静的"を行うだけで、foo()をグローバル名前空間から守ることができます。 "C"リンケージ関数*をC++コードへのポインタ*として渡すことができないということについてのビットは奇妙に思えます。リンケージはabout * naming *ですが、関数へのポインタは物理アドレスに関するものです。彼らは直感的なアイデアのようです。それでは、もう一度、言語弁護士としての私の日は、過去には遠いので、.... –