Consider this example:
int foo(void);
extern "C" int foo(void);
int main()
{
return foo();
}
It errors out with:
$ g++ -c main.cpp
main.cpp:2:16: error: conflicting declaration of ‘int foo()’ with ‘C’ linkage
2 | extern "C" int foo(void);
| ^~~
main.cpp:1:5: note: previous declaration with ‘C++’ linkage
1 | int foo(void);
| ^~~
Which is perfectly fine.
But lets swap first 2 lines:
extern "C" int foo(void);
int foo(void);
int main()
{
return foo();
}
Now it compiles without any error, but the C linkage is chosen, even though C++ linkage is found the last.
Questions:
- Why case 2 compiles and case 1 fails? I would expect them to behave the same way.
- For the case 2 which compiles, why C linkage is chosen and is it possible to change that?
Background: I have a C++ program where the function name occasionally clashed with the one in a C standard library. I would expect an error in such case, but it compiled fine and the wrong linkage was chosen. I need to either find a way of making it to fail consistently (to fix all such cases), or to force the selection of a C++ linkage for all conflicting functions.