Are extern “C” functions a separate type?
-
02-07-2021 - |
質問
From the C++11 draft, 7.5 (para. 1):
Two function types with different language linkages are distinct types even if they are otherwise identical.
So I can do overload based on language linkages:
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);
}
But, with GCC 4.7.1 this sample code gives the error messages:
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
And with 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)
^
Now the questions:
Is my understanding of the standard correct? Is this code valid?
Does anybody know if these are bugs in the compilers or if they are intentionally doing it that way for compatibility purposes?
解決
It's a known bug in gcc, and they record that it's non-conforming since this bug blocks the uber-bug, "C++98 conformance issues".
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316
Check the creation date.
There's some discussion towards the end, about the practicalities of introducing a fix. So the answer to your last question is "both": it's a bug and the bug has intentionally been left in for compatibility.
Other compilers with the same issue might have made the error independently, but I think more likely they also know that it's wrong but want to be bug-compatible with gcc.
他のヒント
The code is clearly valid. G++ (and a number of other compilers) are a bit lax (to put it mildly) about integrating the linkage into the type.
For what it's worth, this code also fails to compile with default settings in 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