Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top