|
|
|
|
|
by LegibleCrimson2
701 days ago
|
|
Ah, yeah, you're right. I was spacing the fact that C as well as C++ can have multiple calling convention. I blame early morning brain. As far as the wrong calling convention goes, I'm basing it on the fact that an extern "C++" function can be passed as a callback where an extern "C" is demanded. Even if they're the same calling convention, that should fail, but it doesn't. Looks like it doesn't fail at runtime, which is a small comfort, but given the different permissiveness of different compilers, it still makes me very nervous to pass a C++ function as a C callback and just hope that it works, given that it isn't guaranteed in the standard. |
|
It's an interesting question. According to the standard, functions with different language linkage are indeed considered different types. As a consequence, <cstdlib> should declare two overloads for qsort() that only differ in the type of the sort function. However, modern compilers don't seem to care:
"The only modern compiler that differentiates function types with "C" and "C++" language linkages is Oracle Studio, others do not permit overloads that are only different in language linkage, including the overload sets required by the C++ standard"
https://en.cppreference.com/w/cpp/language/language_linkage
In practice, extern "C" does two things (as you correctly pointed out):
1. disable name mangling - This only affects the symbol name and is not relevant for callback functions
2. enforce the (default) C calling convention - On all (modern) platforms I know, C and C++ have the same default calling convention for free functions.
This means that from the view of a C++ compiler, pointers to `foo()` and `extern "C" foo()` have the exact same type.
Anyway, no need to be nervous. Even if the compiler treated these as different types, you would get a compiler error because C++ disallows implicit casts between different pointer types.