shantanu
shantanu

Reputation: 2418

Linking error c and c++ (undefined reference)

abc.c file

#include "abc.h"
int abc()
{
    return 10;
}

abc.h file

int abc();

mymain.cpp file

#include "abc.h"
int main()
{
    abc();
    return  0;
}

Makefile

CC=gcc -O2 
CP=g++

mymain: mymain.o abc.o
    $(CP) -o mymain mymain.o abc.o

mymain.o: mymain.cpp abc.h
    $(CP) -c mymain.cpp abc.h

abc.o: abc.c abc.h
    $(CC) -c abc.c abc.h

clean:  
    $(RM) *.o mymain

output

g++ -c mymain.cpp abc.h
gcc -O2  -c abc.c abc.h
g++ -o mymain mymain.o abc.o
mymain.o: In function `main':
mymain.cpp:(.text+0x5): undefined reference to `abc()'
collect2: error: ld returned 1 exit status
make: *** [mymain] Error 1

Why abc() is undefined reference ??

UPDATE

new abc.h

extern "C" {
    int abc();
}

error

g++ -c mymain.cpp abc.h
gcc -O2  -c abc.c abc.h
In file included from abc.c:1:0:
abc.h:1:8: error: expected identifier or ‘(’ before string constant
 extern "C" {
        ^
abc.h:1:8: error: expected identifier or ‘(’ before string constant
 extern "C" {
        ^
make: *** [abc.o] Error 1

Upvotes: 3

Views: 6521

Answers (1)

mah
mah

Reputation: 39797

The problem is you're trying to link a C function into a C++ object, without telling the compiler this is what you're doing.

If your header file (abc.h) looked like this:

extern "C" {
    int abc();
}

it would work (when included into a C++ source... but would break when included into a C source).

You can enclose the extern "C" { and its trailing } within macros as shown in Combining C++ and C - how does #ifdef __cplusplus work? in order to be suitable for both C and C++ inclusion.

Note that $(CP) -c mymain.cpp abc.h in your makefile does not make sense -- you don't want to specify the header on your compiler command line. This goes for both instances of that pattern.

Upvotes: 9

Related Questions