Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ linking error with multiple definition on linux

I am trying to compile a code and it’s getting a linking error with multiple definitions. Unfortunately, I am not able to fix it and any help would be appreciated.

I have following files: Header files: CEST.h; CEST_UI.h; GlobalVariable.h;
Source file: CEST.cpp; CEST_UI.cpp; GlobalVariable.cpp

All parameters, which are claimed to have multiple definitions, are defined in “GlobalVariable.h” and initialized in “GlobalVariable.cpp”.

I am including “GlobalVariable.h” twice: once in CEST.cpp and second time in CEST_UI.cpp.

I was thinking that the following guard in “GlobalVariable.h” would have protected me aginst multiple definition linking error:

# ifndef GLOBALVARIABLE_H
#define GLOBALVARIABLE_H
………….
………….
#endif

I am also attaching “GlobalVariable.h” and “GlobalVariable.cpp” so that you can have a look.

In “GlobalVariable.h”

# ifndef GLOBALVARIABLE_H
#define GLOBALVARIABLE_H

    #include <vector>
    ////////////////////////////////////////
    extern long lFA_MTPulse;
    extern long lNoOfMTPulses;
    extern long ltDK_MTPulse_Duration_us;
    //extern long ltDK_MTPulse_Delay_us;
    extern long ltDK_Wait_After_MT_us;
    extern long ltDK_Wait_After_MTSpoil_us;
    extern long lNoOfMTPulses_PerRTEB;
    extern long ltDK_PreAcqCESTPulseTime_ms;
    extern long ltDK_PreAcqCESTPulseTime_us;
    extern long lTest_XgradStrength;
    //double TR_MTPulse_Remain = 0.0;                                                                   // CEST This will be calculated later 
    long ltDK_TR_MTPulse_us;
    long ltDK_TimeNeeded_for_sMTCSpoilerOnly;
    long ltDK_MTBlockTime_DK;

    ////////////////////////////////////////
    extern double dBWTimeProd;
    extern double dSpoilerCTRL;
    extern double dOffResonance_Rel;
    ////////////////////////////////////////
    long No_of_Samples = (long)512;                                                                     // CEST
    long lNo_of_MTPulses_PreAcq;
    //static sRF_PULSE  sRfMSat1("sRfMSat");                                                        // CEST("sRfMSat")

    extern long lNoOfKSpaceAcq_PerCEST_ArrayValues[];


#endif

In GlobalVariable.cpp

// NOTE: usually name of any parameters is prefixed by type e.g. 
// I am introducing another parameter with prefix "ltDK_" for "long-time" parameter 
//
long lFA_MTPulse = 100;
long lNoOfMTPulses = 1;
long ltDK_MTPulse_Duration_us = 10000;
//long ltDK_MTPulse_Delay_us = 10000;
long ltDK_Wait_After_MT_us = 0;
long ltDK_Wait_After_MTSpoil_us = 0;
long ltDK_PreAcqCESTPulseTime_ms = 3500;                                                // in micro sec 
long ltDK_PreAcqCESTPulseTime_us = (long)((double)ltDK_PreAcqCESTPulseTime_ms*1000);    // in milli sec
long lTest_XgradStrength = 0;

long lNoOfMTPulses_PerRTEB = 30;
double dBWTimeProd = 1.79;
double dSpoilerCTRL = 1.0;
double dOffResonance_Rel = 0.0;
long lNoOfKSpaceAcq_PerCEST_ArrayValues[5] = {1, 3, 5, 7, 9};
like image 496
Garima Singh Avatar asked Sep 12 '13 11:09

Garima Singh


People also ask

What is multiple definition error in C?

If you put a definition of a global variable in a header file, then this definition will go to every . c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.

How do I fix multiple definitions in main?

The main function is the entry point for the C++ program execution. The fix for the error is to scan the source files listed in the build log and remove the unwanted main routines in the respective files. We can have one definition of the main function for the project to run.

How do I fix linker errors?

You can fix the errors by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass . obj files or . lib files that contain the definitions to the linker.


1 Answers

You must declare every variable as extern in the .h file, otherwise it will exist in each .c file that include the .h.

extern means that the linker find the variables in another file, in you case it'll find the variables in GlobalVariables.o

Also, you need to understand that #include insert the text of the .h in your .c, so each statement in the .h is repeated in each .c. This is what happens to ltDK_TR_MTPulse_us for instance: it is declared in both CEST.cpp and CEST_UI.cpp, so the linker sees two variables of the same name, which is forbidden.

like image 77
Benoit Blanchon Avatar answered Sep 26 '22 14:09

Benoit Blanchon