Yuan Wen
Yuan Wen

Reputation: 1711

undefined reference to `func()'

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

Answers (2)

JeremyP
JeremyP

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

Some programmer dude
Some programmer dude

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

Related Questions