c++cxcode

<function> referenced from; symbol(s) not found


I have a piece of C code that is used from a C++ function. At the top of my C++ file I have the line: #include "prediction.h"

In prediction.h I have this:

#ifndef prediction  
#define prediction  

#include "structs.h"  

typedef struct {  
    double estimation;  
    double variance;  
} response;

response runPrediction(int obs, location* positions, double* observations,
                        int targets, location* targetPositions);

#endif

I also have prediction.c, which has:

#include "prediction.h"  

response runPrediction(int obs, location* positions, double* observations,
                        int targets, location* targetPositions) {  
    // code here  
}

Now, in my C++ file (which as I said includes prediction.h) I call that function, then compile (through Xcode) I get this error:

"runPrediction(int, location*, double*, int, location*)", referenced from:
mainFrame::respondTo(char*, int)in mainFrame.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

prediction.c is marked for compilation for the current target. I don't have any problems with other .cpp files not being compiled. Any thoughts here?


Solution

  • Likely the name of the function is being mangled*. You need to do the following:

    extern "C" response runPrediction(int obs, location* positions,
                       double* observations, int targets, location* targetPositions);
    

    Which tells it to treat it as a C function declaration.

    *C++ mangles function names to give them unique names during the linking phase, for function overloading. C has no function overloading so does no such thing.


    Just so you know, you can also make an extern "C" block, if you have multiple things to extern:

    extern "C"
    {
        response runPrediction(int obs, location* positions,
                       double* observations, int targets, location* targetPositions);
    
        // other stuff
    }
    

    And like Paul suggests, to allow the header to be used in both use __cplusplus to condition it:

    #ifdef __cplusplus
        #define EXTERN_C extern "C"
    #else
        #define EXTERN_C
    #endif
    
    EXTERN_C response runPrediction(int obs, location* positions,
                       double* observations, int targets, location* targetPositions);