.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



  • Wooh!
    Kind of Holiday/Vacation presents all these posts, now that I came from vacation. Thank you all for the support


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.