I don't know of any platforms where the ABI is different, but even if the C and C++ calling conventions are the same, the C++ standard requires the compiler to issue a diagnostic for the program. A pointer-to-function-with-C-language-linkage is a different type to a pointer-to-function-with-C++-language-linkage, so you should be able to overload run()
like so:
extern "C" int run(int (*f)(int), int x) { return f(x); }
extern "C++" int run(int (*f)(int), int x) { return f(x); }
Now when you call run(times)
it should call the second one, so it follows that the first one is not callable (there is no conversion from pointer-to-function-with-C-language-linkage to a pointer-to-function-with-C++-language-linkage) and so the original code should cause a compiler diagnostic. Most compilers get that wrong, though, e.g. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316
N.B. The Solaris compiler does diagnose the incompatible language linkages, as a warning:
"t.c", line 11: Warning (Anachronism): Formal argument f of type extern "C" int(*)(int) in call to run(extern "C" int(*)(int), int) is being passed int(*)(int).
If you overload run
with an extern "C++"
function it correctly calls the extern "C++"
one for run(times)
.