Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are extern "C" functions a separate type?

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?

like image 375
rodrigo Avatar asked Sep 18 '12 09:09

rodrigo


People also ask

What is an extern function in C?

extern "C" specifies that the function is defined elsewhere and uses the C-language calling convention. The extern "C" modifier may also be applied to multiple function declarations in a block. In a template declaration, extern specifies that the template has already been instantiated elsewhere.

Can you use extern C in C?

By declaring a function with extern "C" , it changes the linkage requirements so that the C++ compiler does not add the extra mangling information to the symbol. This pattern relies on the presence of the __cplusplus definition when using the C++ compiler. If you are using the C compiler, extern "C" is not used.

Can a function be extern?

the extern keyword is used to extend the visibility of variables/functions. Since functions are visible throughout the program by default, the use of extern is not needed in function declarations or definitions. Its use is implicit. When extern is used with a variable, it's only declared, not defined.

Why do we use extern C?

Using extern "C" lets the compiler know that we want to use C naming and calling conventions. This causes the compiler to sort of entering C mode inside our C++ code. This is needed because C++ compilers mangle the names in their symbol table differently than C compilers and hence behave differently than C compilers.


2 Answers

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.

like image 124
James Kanze Avatar answered Sep 19 '22 07:09

James Kanze


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.

like image 44
Steve Jessop Avatar answered Sep 21 '22 07:09

Steve Jessop