.c file in project compiles but gives undefined reference
-
I created a class that used pure c source code in a .c source file. This code provides geoidetic calculation. The problem was that the code compiled properly but linker returned unreferenced file. Checking the Makefile, I notecied the correspondend .o file was created but the class that needed the code was not linked to it. Tried many approaches but changing .c to .cpp was what solved the problem.
What exactly is going on!? Is it a bug or I am missing some settings? -
.c files are compiled using a C compiler rather than a C++ compiler. The problem you are facing is caused by the c++ name mangling. You can solve this either by compiling using the c++ compiler (as you implicitly did by changing the file extension) or you can use the following technique:
@
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void myCFunction();
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
@
This will tell the c++ compiler to use C symbols during linking rather than C++ symbols. -
The "C++ FAQ":http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html has a section about mixing C and C++ code. It's worth checking out if you want to know a bit more.
-
C++ does some name mangling to encode all the information of functions (name, parameters, return type etc), whereas C does not do this (or does it differently, depending on the compiler).
See http://en.wikipedia.org/wiki/Name_mangling, especially the section on "Handling of C symbols when linking from C++"
The solution is to either compile the C code as C++ file (no problem, as C++ is a superset of C) or to wrap the C code in
@
#ifdef __cplusplus
extern "C" {
#endif
/* ... */
#ifdef __cplusplus
}
#endif
@That does apply for header files too.
-
Accordingly to C++ FAQ link that Franzk gave
@
// c.h
#ifdef __cplusplus
extern "C" {
#endif
int c_func( void );
#ifdef __cplusplus
}
#endif
@@
//c.c
#include <stdio.h>#include "c.h"
int c_func( void )
{
printf("Hi from C function\n");return 42;
}
@@
//main.cpp
#include <QtCore>#include "c.h"
int main( int argc, char** argv )
{
qDebug() << c_func();return 0;
}
@@
######################################################################Automatically generated by qmake (2.01a) Sat Dec 4 02:39:45 2010
######################################################################
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .Input
HEADERS += c.h
SOURCES += main.cpp c.c
@Built and works