18

C++11 ドラフト 7.5 (para. 1) から:

言語リンケージが異なる 2 つの関数型は、それ以外は同一であっても、別個の型です。

したがって、言語リンケージに基づいてオーバーロードを実行できます。

extern "C" typedef void (*c_function)();
typedef void (*cpp_function)();

void call_fun(c_function f)
{
}
void call_fun(cpp_function f)
{
}

extern "C" void my_c()
{
}
void my_cpp()
{
}
int main()
{
    call_fun(my_c);
    call_fun(my_cpp);
}

ただし、GCC 4.7.1 では、このサンプル コードでエラー メッセージが表示されます。

test.cpp: In function 'void call_fun(cpp_function)':
test.cpp:7:6: error: redefinition of 'void call_fun(cpp_function)'
test.cpp:4:6: error: 'void call_fun(c_function)' previously defined here

そして CLang++ で:

test.cpp:7:6: error: redefinition of 'call_fun'
void call_fun(cpp_function f)
     ^
test.cpp:4:6: note: previous definition is here
void call_fun(c_function f)
     ^

今質問:

  • 標準に対する私の理解は正しいですか?このコードは有効ですか?

  • これらがコンパイラのバグなのか、それとも互換性のために意図的にそうしているのか、誰か知っていますか?

4

3 に答える 3

10

コードは明らかに有効です。G ++(および他の多くのコンパイラー)は、リンケージを型に統合することについて(穏やかに言えば)少し緩いです。

于 2012-09-18T09:58:15.760 に答える
8

これは gcc の既知のバグであり、このバグは「C++98 準拠の問題」という超バグをブロックするため、非準拠であると記録されています。

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316

作成日を確認してください。

修正を導入することの実用性について、最後にいくつかの議論があります。したがって、最後の質問に対する答えは「両方」です。これはバグであり、バグは互換性のために意図的に残されています。

同じ問題を抱えた他のコンパイラが個別にエラーを起こした可能性がありますが、それが間違っていることを知っていて、gcc とのバグ互換性を望んでいる可能性が高いと思います。

于 2012-09-18T10:09:52.093 に答える
1

価値があるのは、このコードも VS2012 のデフォルト設定でコンパイルに失敗することです。

(8) error C2084: function 'void call_fun(c_function)' already has a body
(4) see previous definition of 'call_fun'
(19) error C3861: 'call_fun': identifier not found
(20) error C3861: 'call_fun': identifier not found
于 2012-09-18T12:14:09.773 に答える