Reputation: 1711
I'm making some change to an existing linux c project.
In /vobs/ua/HDL/VHDL/CmdUtil/src/help.c
, I define func like this:
void func(){
...
}
In file /vobs/ua/HDL/Interface/cli/src/cliSystem.C
, I write this code:
extern void func();
...
void func1(){
...
func();
...
}
In file /vobs/ua/HDL/VHDL/DsnMgr/src/shell.c
, I write this:
extern void func();
...
void func2(){
...
func();
...
}
In file /vobs/ua/HDL/VHDL/DsnMgr/src/shell.c
, I write this:
extern void func();
...
void func2(){
...
func();
...
}
In file /vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
, I write this:
extern void func();
...
void func3(){
...
func();
...
}
I didn't declare func in any header files.
The problem is, for the call to func in vobs/ua/HDL/Interface/cli/src/cliSystem.C and /vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C, there is error
undefined reference to `func()'
But for /vobs/ua/HDL/VHDL/DsnMgr/src/shell.c
, there is no error.
After I declare func
in vobs/ua/HDL/Interface/cli/src/cliSystem.C
and /vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
like this:
extern "C" void func();
There is no error in /vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
, but the error in vobs/ua/HDL/Interface/cli/src/cliSystem.C
persists.
What's wrong? What can I do to eliminate this error?
Upvotes: 0
Views: 474
Reputation: 86691
C++ has a thing called name mangling so that you can overload functions. If you are compiling code as C++, the declaration
extern void func(void);
will add extra characters to its name to encode the fact that it has no parameters. You can disable this by telling the C++ compiler to use C conventions:
extern "C" void func(void);
or
extern "C" {
void func(void);
}
It's normal, however to put these in a header that can be included from both C and C++ files:
#if defined __cplusplus
extern "C" {
#endif
void func(void);
// other function declarations
#if defined __cplusplus
}
#endif
Upvotes: 1
Reputation: 409442
The problem is that the function func
is a C function, and you try to call it from a C++ function. This is problematic because C++ does something called name mangling to allow things like function overload.
That means when you do your declaration
extern void func();
the C++ compiler will mangle the symbol and that mangled symbol will not be found.
In C++ you have to inhibit this name mangling for functions that comes from C object files. This is done with a special extern
declaration:
extern "C" void func();
On a slightly related note, in C a declaration like
void func();
doesn't mean that the function takes no arguments like it does in C++. In C that declaration means that func
takes an unspecified number of unspecified arguments. In C you must use void
to declare a function that takes no arguments:
void func(void);
Upvotes: 2