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< – 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 – Johnny Mopp 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
  • Thanks a lot, it works! – Ivan Feb 20 '14 at 16:19

2 Answers2

4
extern "C" void sol()
{
    cout<<"HW!!\n";
}
Mike Seymour
  • 242,813
  • 27
  • 432
  • 630
BlackMamba
  • 9,652
  • 6
  • 42
  • 61
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,074
  • 4
  • 47
  • 69
  • 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