Reputation: 2418
#include "abc.h"
int abc()
{
return 10;
}
int abc();
#include "abc.h"
int main()
{
abc();
return 0;
}
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
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 ??
extern "C" {
int abc();
}
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
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