multiple definition error - global variable header file

Discussion in 'C++' started by Bram Kuijper, Jun 27, 2007.

  1. Bram Kuijper

    Bram Kuijper Guest

    Hi all,

    I am having a classical 'multiple definition error' of a global
    variable, but this time I cannot find a good explanation of how to
    prevent this multiple definition error.

    I defined a global variable, needed by some functions, inside a header
    file with ifndef clauses in order to prevent multiple definition:

    #ifndef _MYRANDOM_H_
    #define _MYRANDOM_H_

    long int idum;
    long int idum2;

    // some function declarations etc

    #endif
    // end of header file


    The functions declared in this header file are put in a static library.
    Subsequently, this static library is used by a number of other static
    libraries. Compiling these static libraries does not yield any errors.

    Next to that I compile a program using those static libraries and
    subsequently the errors surface. Errors like:

    /home/bram/Varsity/C++/Simulation_classes/Trait/express.cpp:48: multiple
    definition of `idum'
    /tmp/cciYexgh.o:/home/bram/Varsity/genconfl/haplodiploidy/spatial/main.cpp:14:
    first defined here
    /home/bram/lib/libtrait.a(express.o): In function
    `__static_initialization_and_destruction_0':
    /home/bram/Varsity/C++/Simulation_classes/Trait/express.cpp:48: multiple
    definition of `idum2'
    /tmp/cciYexgh.o:/home/bram/Varsity/genconfl/haplodiploidy/spatial/main.cpp:14:
    first defined here
    /home/bram/lib/libtrait.a(inherit.o): In function
    `__static_initialization_and_destruction_0':
    /home/bram/include/gene.h:55: multiple definition of `idum'

    How can it be that when I use this header file, the variables are
    redefined _despite_ me using #ifndef clauses? I am using g++ 4.1.3 on a
    ubuntu linux box and I did not define any of those variables outside the
    header file.

    thanks in advance,

    Bram
     
    Bram Kuijper, Jun 27, 2007
    #1
    1. Advertising

  2. Bram Kuijper

    Colander Guest

    On Jun 27, 3:33 pm, Bram Kuijper <> wrote:
    > Hi all,
    >
    > I am having a classical 'multiple definition error' of a global
    > variable, but this time I cannot find a good explanation of how to
    > prevent this multiple definition error.


    > #ifndef _MYRANDOM_H_

    (as a side note, it's better to use __MYRANDOM_H__, stuff starting
    with an _ and followed by a capital is reserved for implementation)

    > The functions declared in this header file are put in a static library.
    > Subsequently, this static library is used by a number of other static
    > libraries. Compiling these static libraries does not yield any errors.
    >
    > Next to that I compile a program using those static libraries and
    > subsequently the errors surface. Errors like:


    I think you variable is present in the library AND in the executable.
    To test this you can first compile your lib, change the headers so the
    global var is gone and the compile your program, the error should be
    gone. Later on you can simulate the removing trick with some xtrat
    define that is defined for the lib but not for the program.

    Veel succes,
    Bas
     
    Colander, Jun 27, 2007
    #2
    1. Advertising

  3. Bram Kuijper

    Bram Kuijper Guest

    >
    > I think you variable is present in the library AND in the executable.
    > To test this you can first compile your lib,


    okay, compiled my libraries with the global variables still in there


    change the headers so the
    > global var is gone


    commented out the global variables.

    and the compile your program, the error should be
    > gone.


    subsequently, I compiled the program, now including the header in which
    the global vars are commented out.

    Unfortunately the errors are still there. I have no clue:


    g++ -g -Wall -I/home/bram/include -L/home/bram/lib -o spatial main.cpp
    -lsimulation -lparameters -lworld -lpatch -lindividual -ltrait -lgene
    -lbramrandom
    /home/bram/lib/libsimulation.a(run.o): In function
    `__static_initialization_and_destruction_0':
    /home/bram/Varsity/C++/Simulation_classes/Simulation/run.cpp:29:
    multiple definition of `idum'
    /tmp/ccTdhYH6.o:/home/bram/Varsity/genconfl/haplodiploidy/spatial/main.cpp:14:
    first defined here
    /home/bram/lib/libsimulation.a(run.o): In function
    `__static_initialization_and_destruction_0':
    /home/bram/Varsity/C++/Simulation_classes/Simulation/run.cpp:29:
    multiple definition of `idum2'
    /tmp/ccTdhYH6.o:/home/bram/Varsity/genconfl/haplodiploidy/spatial/main.cpp:14:
    first defined here
    /home/bram/lib/libsimulation.a(simulation.o): In function
    `__static_initialization_and_destruction_0':
    /home/bram/include/parameters.h:11: multiple definition of `idum'
    /tmp/ccTdhYH6.o:/home/bram/Varsity/genconfl/haplodiploidy/spatial/main.cpp:14:
    first defined here
    /home/bram/lib/libsimulation.a(simulation.o): In function
    `__static_initialization_and_destruction_0':
    /usr/include/c++/4.1.3/bits/stl_vector.h:96: multiple definition of `idum2'
    /tmp/ccTdhYH6.o:/home/bram/Varsity/genconfl/haplodiploidy/spatial/main.cpp:14:
    first defined here
    /home/bram/lib/libworld.a(disperse.o): In function
    `__static_initialization_and_destruction_0':
    /usr/include/c++/4.1.3/bits/stl_vector.h:95: multiple definition of `idum'
    /tmp/ccTdhYH6.o:/home/bram/Varsity/genconfl/haplodiploidy/spatial/main.cpp:14:
    first defined here
    /home/bram/lib/libworld.a(disperse.o): In function
    `__static_initialization_and_destruction_0':
    /usr/include/c++/4.1.3/bits/stl_vector.h:96: multiple definition of `idum2'
     
    Bram Kuijper, Jun 27, 2007
    #3
  4. Bram Kuijper

    Marcus Kwok Guest

    Colander <> wrote:
    > On Jun 27, 3:33 pm, Bram Kuijper <> wrote:
    >> #ifndef _MYRANDOM_H_

    > (as a side note, it's better to use __MYRANDOM_H__, stuff starting
    > with an _ and followed by a capital is reserved for implementation)


    That's even worse. Identifiers with a double-underscore (I think it may
    be anywhere in the name) are also reserved for the implementation.

    However, trailing underscores are OK. I would use MYRANDOM_H_ or
    something like that.

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
     
    Marcus Kwok, Jun 27, 2007
    #4
  5. Bram Kuijper

    Colander Guest

    On Jun 27, 4:18 pm, (Marcus Kwok) wrote:
    > Colander <> wrote:
    > > On Jun 27, 3:33 pm, Bram Kuijper <> wrote:
    > >> #ifndef _MYRANDOM_H_

    > > (as a side note, it's better to use __MYRANDOM_H__, stuff starting
    > > with an _ and followed by a capital is reserved for implementation)

    >
    > That's even worse. Identifiers with a double-underscore (I think it may
    > be anywhere in the name) are also reserved for the implementation.
    >


    Damn, thanks, I will remember that one!
     
    Colander, Jun 27, 2007
    #5
  6. Bram Kuijper

    joe Guest

    On Jun 27, 9:33 am, Bram Kuijper <> wrote:
    >
    > long int idum;
    > long int idum2;


    Your header guards are insufficient to prevent double definition
    errors because there is more than one compilation unit including the
    header. Each .cpp which includes the header will define its own
    globals. The header guard only prevents a single compilation unit
    from including the header more than once. What you need to do is
    something like one of the following...

    suggestion 1: Change the declarations in your header to:

    extern long int idum;
    extern long int idum2;

    Then actually define these guys in one of your .cpp files.

    suggestion 2: Modify your header to something like:

    #ifdef DEFINE_GLOBALS
    #define GLOBAL
    #else // !DEFINE_GLOBALS
    #define GLOBAL extern
    #endif

    GLOBAL long int idum;
    GLOBAL long int idum2;

    One of your .cpp files should define "DEFINE_GLOBALS" prior to
    including this header. The only real advantage of this method over
    the 1st is that you are then guaranteed that your definition and
    declarations match.

    Suggestion 3: Encapsulate the globals into one .cpp and provide
    accessors to access/set the globals. This one is a bit of fuss, so I
    don't like it so much, but...

    long get_idum();
    set_idum(long);

    long get_idum2();
    set_idum(long);

    then in a .cpp you define:

    long int idum;
    long int idum2;

    long int get_idum()
    {
    return idum;
    }

    void set_idum(long int v)
    {
    idum = v;
    }
    ..
    ..
    ..


    You should also consider putting your globals in your own namespace so
    that they can't conflict with any other globals in the system.

    Hope that helps,
    joe
     
    joe, Jun 27, 2007
    #6
  7. Bram Kuijper

    red floyd Guest

    Colander wrote:
    > On Jun 27, 3:33 pm, Bram Kuijper <> wrote:
    >> Hi all,
    >>
    >> I am having a classical 'multiple definition error' of a global
    >> variable, but this time I cannot find a good explanation of how to
    >> prevent this multiple definition error.

    >
    >> #ifndef _MYRANDOM_H_

    > (as a side note, it's better to use __MYRANDOM_H__, stuff starting
    > with an _ and followed by a capital is reserved for implementation)
    >


    WRONG WRONG WRONG! You are correct in that _ followed by upper case is
    reserved, but any identifier containing a double underscore is also so
    reserved. He should use MYRANDOM_H_
     
    red floyd, Jun 27, 2007
    #7
  8. Bram Kuijper

    James Kanze Guest

    On Jun 27, 3:49 pm, Colander <> wrote:
    > On Jun 27, 3:33 pm, Bram Kuijper <> wrote:


    > > I am having a classical 'multiple definition error' of a global
    > > variable, but this time I cannot find a good explanation of how to
    > > prevent this multiple definition error.
    > > #ifndef _MYRANDOM_H_


    > (as a side note, it's better to use __MYRANDOM_H__, stuff starting
    > with an _ and followed by a capital is reserved for implementation)


    As is anything containing two adjacent underscore. And anything
    at all beginning with an underscore in the global namespace (and
    thus, macros).

    > > The functions declared in this header file are put in a static library.
    > > Subsequently, this static library is used by a number of other static
    > > libraries. Compiling these static libraries does not yield any errors.


    > > Next to that I compile a program using those static libraries and
    > > subsequently the errors surface. Errors like:


    > I think you variable is present in the library AND in the executable.


    I think his problem is that the definition is present in every
    translation unit that includes the header. Include guards only
    prevent multiple definitions in a single translation unit; they
    have no effect between translation units. What he needs to do
    is replace the definitions in the header with declarations, and
    provide a definition in a single source file, e.g.:

    in header:
    // ...
    extern long int idum ;
    extern long int idum2 ;
    // ...

    and in a single source file (which preferably includes the
    header):

    long int idum = ... ;
    long int idum2 = ... ;

    (Note that unlike a function declaration, a data declaration is
    a definition unless it is explicitly declared extern.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 28, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lu
    Replies:
    2
    Views:
    760
    Mark McIntyre
    Jul 8, 2003
  2. Replies:
    1
    Views:
    405
    Michael Ekstrand
    Aug 21, 2005
  3. Replies:
    11
    Views:
    1,275
    Ian Collins
    Aug 5, 2006
  4. Pierre Yves
    Replies:
    2
    Views:
    526
    Pierre Yves
    Jan 10, 2008
  5. mlt
    Replies:
    2
    Views:
    911
    Jean-Marc Bourguet
    Jan 31, 2009
Loading...

Share This Page