2011-01-25 21 views
3

私は、関数ポインタを引数(例えばqsort)として取るC標準ライブラリの関数を使用する場合、その関数関数ポインタを渡す必要があるのは、C関数である必要があるため、extern "C"として宣言します。qsortをC++関数へのポインタで呼び出す

extern "C" { 
    int foo(void const* a, void const* b) {...} 
} 

... 
qsort(some_array, some_num, some_size, &foo); 

これは間違った情報ですが、私は驚くことはありませんが、これは正しいですか?

+0

参照:http://www.parashift.com/c++-faq-lite/pointers-to-members.html – Thomi

+0

@Thomi:上記のfooはメンバ関数ではありません。したがって、提供されたFAQエントリはあまり意味がありません。 –

+0

@Billy ONeal:[33.2]は実際にそれを言います、私のコメントを最初の答えに見てください。 – DaVinci

答えて

5

多くのことは、現在使用しているコンパイラの実用的な答えに興味があるか、C++のすべての可能な適合実装をカバーする理論的な答えに気を付けるかどうかによって異なります。理論的にはそれは必要です。実際には、通常はそれなしで得ることができます。

実際の質問は、コンパイラが、C関数を呼び出すときとは異なるグローバルなC++関数を呼び出すために、別の呼び出し規約を使用するかどうかです。 ほとんどのコンパイラはどちらの方法でも同じ呼び出し規約を使用しているため、extern "C"宣言なしで呼び出しが機能します。

しかし、理論的には、理論上、2つの呼び出し規約を異なるものにするコンパイラが存在する可能性があります。少なくとも、私はそのようなコンパイラについてはわかりませんが、周りのコンパイラの数を考えると、私が知らないものがあれば私はひどく驚くことはありません。

OTOH、それは別の質問を起こします:もしあなたがC++を使っているのであれば、どうしてあなたはqsortを使っていますか? C++では、ほとんどの場合、std::sortが好まれます。使いやすく、通常は高速です。

+0

使いやすく、より速く**タイプセーフ**です。 –

+0

@Karl:良い点。 –

+2

'qsort'は特別かもしれません。 C++標準では、 '' qsort'、 'bsearch'、' atexit' *は "C++"リンケージ*と "C"リンケージの実装で宣言しなければなりません。他の標準的なCの関数については、それらがどのような関係になっているかは実装定義されています。私はこれの意図や効果がどういうものか分かりませんが、これが関数ポインタのパラメータに影響を与えるかどうかについては何も見ていませんが、コールバックを取るこれらの標準的なC関数C++ではこの追加要件があります。 –

5

これは間違った情報です。

extern Cは、C++ライブラリをCバイナリにリンクする必要がある場合に必要です。 Cリンカーは関数名を見つけることができます。これは関数ポインターの問題ではありません(関数がCコードで名前で参照されていないため)。

+3

しかし、リンク@thomiもコメントとして投稿: 'Cリンケージはネームマングリングのようなものをカバーしていないので、実際にはextern" C "非メンバ関数でなければなりませんCとC++で異なるかもしれない呼び出し規約もあります。[33.2]の 、または私は誤解していますか? – DaVinci

+0

@DaVinci:これは、同じプラットフォーム上のC++とC用のコンパイラでは一般的に同じ呼び出し規約が使用されるため、実際には実際には現れませんが、公正な点です。 –

+0

@DaVinci:技術者を除いて、C関数へのポインタが必要な場所では、静的な*メンバ関数を使うこともできます。 – Clifford

関連する問題