3

I have the following setup:

main.c:

extern void sol();
int main(){
    sol();
}

sol.cc:

#include<iostream>
using namespace std;
void sol(){
    cout<<"HW!!\n";
}

I compile to separate object files:

$gcc main.c -c
$g++ sol.cc -c

But when I try to link them to a single executable,

$g++ main.o sol.o

I get: main.c:(.text+0x7): undefined reference to 'sol' , nm sol.o shows that there is 00000000 T _Z3solv , while nm main.o requires U sol. I found out that C++ renames functions to avoid same names of overloaded functions. Is there any way to tell compiler that sol.o contains renamed functions, or to compile sol.cc without renaming them?

Ivan
  • 63
  • 1
  • 5
  • I think that extern "C" would prevent the rename from happening. ie. extern "C" void sol(){cout<<"HW!!\n";} – bizzehdee Feb 20 '14 at 16:02
  • `extern "C"` http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B#Linking_C_and_C.2B.2B_code – 001 Feb 20 '14 at 16:02
  • It is generally best in a mixed C and C++ program to make the `main()` function a C++ function, even if it consists of `int main(int argc, char **argv) { return c_main(argc, argv); }` in its entirety (with a declaration equivalent to `extern "C" int c_main(int argc, char **argv);` in scope). The original C `main()` is simply renamed to `c_main()` — or `real_main()` or any other name that takes your fancy. – Jonathan Leffler Feb 20 '14 at 16:12

2 Answers2

4
extern "C" void sol()
{
    cout<<"HW!!\n";
}
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
BlackMamba
  • 10,054
  • 7
  • 44
  • 67
2

You have to use the extern "C" declaration to make sol available to C. Put this into a common header:

extern "C" void sol();
Sergey L.
  • 21,822
  • 5
  • 49
  • 75
  • 2
    If you want a common header, you'll need to mess around with `#ifdef __cplusplus`, since `extern "C"` isn't valid in C. – Mike Seymour Feb 20 '14 at 16:08