“undefined reference to” errors when linking stati

2019-01-01 09:50发布

问题:

I have a test file (just for the link test) where I overload the new/delete operators with my own malloc/free library called libxmalloc.a. But I keep getting \"undefined reference to\" error as following when linking the static library, even I change the order of test.o and -lxmalloc. But everything works well with other C programs linking this library. I\'m so confused with this issue and appreciate any clue.

Error Msg:

g++ -m64 -O3 -I/usr/include/ethos -I/usr/include/nacl/x86_64 -c -o test.o test.cpp
g++ -m64 -O3 -L. -o demo test.o -lxmalloc
test.o: In function `operator new(unsigned long)\':
test.cpp:(.text+0x1): undefined reference to `malloc(unsigned long)\'
test.o: In function `operator delete(void*)\':
test.cpp:(.text+0x11): undefined reference to `free(void*)\'
test.o: In function `operator new[](unsigned long)\':
test.cpp:(.text+0x21): undefined reference to `malloc(unsigned long)\'
test.o: In function `operator delete[](void*)\':
test.cpp:(.text+0x31): undefined reference to `free(void*)\'
test.o: In function `main\':
test.cpp:(.text.startup+0xc): undefined reference to `malloc(unsigned long)\'
test.cpp:(.text.startup+0x19): undefined reference to `malloc(unsigned long)\'
test.cpp:(.text.startup+0x24): undefined reference to `free(void*)\'
test.cpp:(.text.startup+0x31): undefined reference to `free(void*)\'
collect2: ld returned 1 exit status
make: *** [demo] Error 1

My test.cpp file:

#include <dual/xalloc.h>
#include <dual/xmalloc.h>
void*
operator new (size_t sz)
{
    return malloc(sz);
}
void
operator delete (void *ptr)
{
    free(ptr);
}
void*
operator new[] (size_t sz)
{
    return malloc(sz);
}
void
operator delete[] (void *ptr)
{
    free(ptr);
}
int
main(void)
{
    int *iP = new int;
    int *aP = new int[3];
    delete iP;
    delete[] aP;
    return 0;
}

My Makefile:

CFLAGS += -m64 -O3 -I/usr/include/ethos -I/usr/include/nacl/x86_64
CXXFLAGS += -m64 -O3
LIBDIR += -L.
LIBS += -lxmalloc
all: demo
demo: test.o
    $(CXX) $(CXXFLAGS) $(LIBDIR) -o demo test.o $(LIBS)
test.o: test.cpp
$(CXX) $(CFLAGS) -c -o $@ $<
clean:
- rm -f *.o demo

回答1:

But everything works well with other C programs linking this library.

Did you notice that C and C++ compilation create different symbol names on object file level? It\'s called \'name mangling\'.
The (C++) linker would show undefined references as demangled symbols in the error message, which might confuse you. If you inspect your test.o file with nm -u you\'ll see that the referenced symbol names don\'t match with those provided in your library.

If you want to use functions linked in as externals that were compiled using the plain C compiler, you\'ll need their function declarations enclosed in an extern \"C\" {} block which suppresses C++ name mangling for everything declared or defined inside, e.g.:

extern \"C\" 
{
    #include <dual/xalloc.h>
    #include <dual/xmalloc.h>
}

Even better, you might wrap your function declarations in your header files like this:

#if defined (__cplusplus)
extern \"C\" {
#endif

/*
 * Put plain C function declarations here ...
 */ 

#if defined (__cplusplus)
}
#endif