Einheri
Einheri

Reputation: 985

GCC: linker error when working with old C code

I'm running into a mysterious situation with the GCC compiler. So I've got the following files:

//main.cpp

#include "mleak_cpp.h"
int main(int argc, char* argv[])
{
    foo();
    __memory_malloc(10,"hello",5);
return 0;
}

//mleak_cpp.h

......
void foo(void);
void* __memory_malloc(size_t size, const char* file, int line);

//mleak_cpp.cpp

//definitions of the functions;
void foo(void){printf("foo\n");

void* __memory_malloc(size_t size, const char* file, int line){
    printf("%s,%d\n",file,line);
    InitDoubleLinkList();

    void* p = malloc(size);
    if(p == NULL)
    return NULL;

    __DuLinkList* pListNode;
    pListNode = (__DuLinkList*)malloc(sizeof(__DuLinkList));

    pListNode->address = p;
    pListNode->memorysize = size;
    pListNode->file = file;
    pListNode->line = line;
    InsertBlockToList(pListNode);
    return p;
}

For some reason, the call to void foo(void) is fine, but the call to "__memory_malloc" goes down with a linker error, "undefined reference" blah blah. What's the difference between the two functions that causes the different behaviour?

I tried adding "extern C" to the "#include" directive, so main.cpp reads:

extern "C"{
    #include "mleak_cpp.h"
}

and adding the keyword "extern" before the declarations of the functions, and this time the call to "foo()" fails too with the same error.

I appreciate any help from you guys

Upvotes: 0

Views: 171

Answers (2)

parkovski
parkovski

Reputation: 1523

extern "C" is for C++, not C, and tells it that the function's name shouldn't be mangled. In C code, you should never see this. Generally, you put it in header files, and you guard it, like this:

#ifdef __cplusplus
extern "C" {
#endif

/* C and C++ compatible header file body here */

#ifdef __cplusplus
} /* end extern "C" */
#endif

If you do it this way though, you need to include the header file in both your C and C++ files, so that the C++ compiler knows to use C linkage.

You can put the extern "C" in front of the function definition in C++ instead and leave it out of the header, but this only works if you only include the headers in C code, so it's recommended to do it the way I pointed out above.

Upvotes: 1

Joe Z
Joe Z

Reputation: 17956

You're placing extern "C" in the wrong place.

If main.c is truly a C file, and mleak_cpp.cpp is truly a C++ function, then you need to put an extern "C" ahead of the definition of __memory_malloc() like so:

extern "C" void* __memory_malloc(size_t size, const char* file, int line){
    // ...
}

If you put extern "C" in the mleak_cpp.h file, it needs to be guarded:

#ifdef __cplusplus
    extern "C" {
#endif 

    /* ... body of header ... */

#ifdef __cplusplus
     }
#endif

Also, it's not clear why foo works in your example above, when one file calls __foo() but the other file defines foo(). I assume something more is at play, such as an editing error in your question.

Upvotes: 3

Related Questions