Question

A C++ module that I'm working with contains a function (FitSpectrumNaIU) that calls two other functions (quadcal and mrqmin), and prototypes for the called functions are included after the first line of the containing function:

/*++ analyze spectral data */
int FitSpectrumNaIU(long iNumChans, long *pSpectrum, double dGain, double dZero,
    double *dCentroid, double *dFWHM, double *dArea, double *dError) {
      double quadcal(double ax, double ay, double bx, double by, double cx, double cy);
      int mrqmin(double *x,double *y,double *sig,int npt,double *a,int *ia,
        int ma, double **covar, double **alpha, double *chisq,
        void (*funcs)(double, double*, double*, double*, int), double *alamda);
      ... (body of FitSpectrumNaIU)

mrqmin() and quadcal() are defined later on in the source file.

The code compiles fine and becomes part of a library that is subsequently linked with a main routine. A problem occurs during linking with Eclipse g++ however. The mrqmin() routine’s name does not get mangled when it is put into the archive and so the linker does not find it. objdump of the library, with a grep for mrqmin (showing just the function definition – there are also static declarations that appear, all mangled), looks like this:

00000000         *UND*  00000000 _Z6mrqminPdS_S_iS_PiiPS_S1_S_PFvdS_S_S_iES_
000058c0 g     F .text  00000a24 mrqmin

There’s a mangled version of the function name that’s as I would expect it and is shown as referenced but undefined, while an unmangled version of the name is marked as defined. At first I thought there must be an extern C statement somewhere that was causing this, but that's not the case.

I would expect mrqmin and quadcal to be handled identically, as there is no real definitional difference between them in the code, but quadcal appears with its name properly mangled in the archive (below) and is found by the linker:

00009068 g     F .text  000002f0 _Z7quadcaldddddd

Eclipse is version 3.3.0 and the CDT is 4.0.1.x and I'm constrained to use these versions. All this links properly in the same form under VS2012, and I’m not sure what to try next. Any ideas?

Was it helpful?

Solution

It sounds like mrqmin is declared as extern "C" when it's compiled and in at least one declaration. This causes the compiler that the function should use C style linkage, which includes not mangling it.

I'm not sure why VS 2012 doesn't exhibit the same problem, but it might have to do with some sort of header inclusion order. I would run the source file of both where it's compiled and where it's used through the preprocessor in g++ (using -E) and VS2012 (not sure how), and see if the extern "C" is present in both.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top