How to avoid multiple definition of a variable by multiple inclusion of a header file

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • lars.uffmann@rwth-aachen.de

    How to avoid multiple definition of a variable by multiple inclusion of a header file

    Easily described problem:

    Using g++ version 3.3.5 under suse 9.3,

    bla.h:
    -----------
    #ifndef myTEST
    #define myTEST
    ZFSInt test;
    #endif
    ------------

    leads to an error at link time...
    application.o(. bss+0x0):/path_here/application.cpp :19: multiple
    definition of `test'
    app.o(.bss+0x0) :/path_here/app.cpp:17: first defined here
    ....for EVERY call of #include "bla.h"
    :(

    Apparently the #ifndef only works at compile time, but somehow causes
    an error at linktime. Any solution? I want the variable "test"
    available in all modules that #include "bla.h"

    Regards,

    Lars Uffmann

  • Howard

    #2
    Re: How to avoid multiple definition of a variable by multiple inclusion of a header file


    <lars.uffmann@r wth-aachen.dewrote in message
    news:1154468416 .870784.303810@ m79g2000cwm.goo glegroups.com.. .
    Easily described problem:
    >
    Using g++ version 3.3.5 under suse 9.3,
    >
    bla.h:
    -----------
    #ifndef myTEST
    #define myTEST
    ZFSInt test;
    #endif
    ------------
    >
    leads to an error at link time...
    application.o(. bss+0x0):/path_here/application.cpp :19: multiple
    definition of `test'
    app.o(.bss+0x0) :/path_here/app.cpp:17: first defined here
    ...for EVERY call of #include "bla.h"
    :(
    >
    Apparently the #ifndef only works at compile time, but somehow causes
    an error at linktime. Any solution? I want the variable "test"
    available in all modules that #include "bla.h"
    >
    First, copy the definition of test above into an implementation file you'll
    always link with (one which includes the header file where the definition of
    ZFSInt resides). Then, preface the above declaration in blah.h with the
    keyword "extern" (followed by at least one space). That tells the compiler
    to look elsewhere for the actual declaration of test, allows other units to
    see the variable through this header, and prevents the linker from seeing
    multiple definitions.

    -Howard



    Comment

    • lars.uffmann@rwth-aachen.de

      #3
      Re: How to avoid multiple definition of a variable by multiple inclusion of a header file

      Howard wrote:
      First, copy the definition of test above into an implementation file you'll
      always link with (one which includes the header file where the definition of
      ZFSInt resides). Then, preface the above declaration in blah.h with the
      keyword "extern" (followed by at least one space).
      Issue solved - thank you! I put the actual declaration in the cpp-file
      belonging
      to the blah.h class definition header file.

      Any link to a website explaining this behaviour of #ifdef / #ifndef ?

      Best Regards,

      Lars

      Comment

      • red floyd

        #4
        Re: How to avoid multiple definition of a variable by multiple inclusionof a header file

        lars.uffmann@rw th-aachen.de wrote:
        Howard wrote:
        >First, copy the definition of test above into an implementation file you'll
        >always link with (one which includes the header file where the definition of
        >ZFSInt resides). Then, preface the above declaration in blah.h with the
        >keyword "extern" (followed by at least one space).
        >
        Issue solved - thank you! I put the actual declaration in the cpp-file
        belonging
        to the blah.h class definition header file.
        >
        Any link to a website explaining this behaviour of #ifdef / #ifndef ?
        That's not a preprocessor issue, it's the ODR (one definition rule).

        Comment

        • lars.uffmann@rwth-aachen.de

          #5
          Re: How to avoid multiple definition of a variable by multiple inclusion of a header file

          red floyd wrote:
          Any link to a website explaining this behaviour of #ifdef / #ifndef ?
          That's not a preprocessor issue, it's the ODR (one definition rule).
          To me, that doesn't explain why
          #ifndef FOO
          #define FOO
          class foo {
          foo(){};
          ~foo(){};
          };

          int test;
          #endif

          successfully avoids multiple class definition but NOT multiple
          declaration of the variable "test" as an integer...

          I used to think #ifdef and the likes were preprocessor commands that
          would completely SKIP sections of code if the condition was not met -
          all the way to the next #endif.
          Apparently this does not work for variable declarations - That's the
          part I do not understand.

          Regards,

          Lars

          Comment

          • red floyd

            #6
            Re: How to avoid multiple definition of a variable by multiple inclusionof a header file

            lars.uffmann@rw th-aachen.de wrote:
            red floyd wrote:
            >>Any link to a website explaining this behaviour of #ifdef / #ifndef ?
            >That's not a preprocessor issue, it's the ODR (one definition rule).
            >
            To me, that doesn't explain why
            #ifndef FOO
            #define FOO
            class foo {
            foo(){};
            ~foo(){};
            };
            >
            int test;
            #endif
            >
            successfully avoids multiple class definition but NOT multiple
            declaration of the variable "test" as an integer...
            >
            I used to think #ifdef and the likes were preprocessor commands that
            would completely SKIP sections of code if the condition was not met -
            all the way to the next #endif.
            Apparently this does not work for variable declarations - That's the
            part I do not understand.
            >
            Because you're defining a class... which is a type. No storage is
            allocated. When you're declaring a variable, storage is allocated.

            The other thing you need to know is that preprocessor commands don't go
            across translation units.

            Comment

            • Marco Costa

              #7
              Re: How to avoid multiple definition of a variable by multiple inclusionof a header file

              lars.uffmann@rw th-aachen.de wrote:
              red floyd wrote:
              >
              >>>Any link to a website explaining this behaviour of #ifdef / #ifndef ?
              >>
              >>That's not a preprocessor issue, it's the ODR (one definition rule).
              >
              >
              To me, that doesn't explain why
              #ifndef FOO
              #define FOO
              class foo {
              foo(){};
              ~foo(){};
              };
              >
              int test;
              #endif
              >
              Let's say that you include this file in two source files. What happens?
              a) The class foo gets its declaration. Good, now you can create foo objects.
              b) The integer test gets allocated. Once in one file and once in the second file.
              Everything is fine until the link stage. The linker will try to make sense of all and will see *two* instances of int test. Which one to use? Nobody will ever be able to answer that.

              The solution,

              extern int test;

              Goes in the header. That will tell to the compiler: There is a variable called test that is to be used, but it is only declared here. Its definition will be done somewhere else.

              Then, in one of your source files, you define this variable on the normal way.
              When you compile, you can refer to this variable in any source code that uses the include file, but at link time, only one instance will exist. At this point, no link error. Hooray!

              I hope I was clear.

              Regards,

              Marco

              Comment

              • Julián Albo

                #8
                Re: How to avoid multiple definition of a variable by multiple inclusion of a header file

                lars.uffmann@rw th-aachen.de wrote:
                Any link to a website explaining this behaviour of #ifdef / #ifndef ?
                You can imagine the preprocessor is a bunch of text editor macros. Do the
                substitutions by hand, or use the commands or options of your compiler that
                shows the preprocessor output, and look the generated code. This result is
                what the "real" compiler see.

                --
                Salu2

                Comment

                • Michiel.Salters@tomtom.com

                  #9
                  Re: How to avoid multiple definition of a variable by multiple inclusion of a header file

                  lars.uffmann@rw th-aachen.de wrote:
                  Easily described problem:
                  >
                  Using g++ version 3.3.5 under suse 9.3,
                  >
                  bla.h:
                  -----------
                  #ifndef myTEST
                  #define myTEST
                  ZFSInt test;
                  #endif
                  ------------
                  >
                  leads to an error at link time...
                  application.o(. bss+0x0):/path_here/application.cpp :19: multiple
                  definition of `test'
                  app.o(.bss+0x0) :/path_here/app.cpp:17: first defined here
                  ...for EVERY call of #include "bla.h"
                  :(
                  >
                  Apparently the #ifndef only works at compile time, but somehow causes
                  an error at linktime. Any solution? I want the variable "test"
                  available in all modules that #include "bla.h"
                  Yes. You want the variable available. That means you'll need a
                  declaration,
                  not the definition. The typical variable declaration is "extern <type>
                  <name>;"
                  You put the definition in a .cpp, just like you would with function
                  definitions.

                  This has nothing to do with #ifdef, which is a preprocessor command. It
                  works only at compile time, and skips every second defintion of 'test'
                  *in
                  a single .cpp*, not across .cpp's. As the compiler works on single
                  ..cpp's
                  it won't notice that.

                  HTH,
                  Michiel Salters

                  Comment

                  • lars.uffmann@rwth-aachen.de

                    #10
                    Re: How to avoid multiple definition of a variable by multiple inclusion of a header file

                    Michiel.Salters @tomtom.com schrieb:
                    This has nothing to do with #ifdef, which is a preprocessor command.
                    It works only at compile time, and skips every second defintion of 'test'
                    *in a single .cpp*, not across .cpp's. As the compiler works on single
                    .cpp's it won't notice that.
                    Woohoo - I see light in the dark! Finally the explanation I've been
                    waiting for :) To be honest, I suspected something like this, because
                    the compiler creates libraries for each cpp file separately, so the
                    linker would spot multiple declarations of the variable, but in that
                    case the sense of the preprocessor commands did not occur to me - I
                    never realized it was only to skip further definitions within the same
                    cpp-File.

                    Thanks for clearing this up! :)
                    And to all the others that helped solving the problem!

                    Regards,

                    Lars

                    Comment

                    • chinthanep@gmail.com

                      #11
                      Re: How to avoid multiple definition of a variable by multiple inclusion of a header file

                      Hi,

                      In my implementation, it is like

                      #ifndef TEST
                      #define TEST
                      const char* strDescriptions[] = {"Desc1", "Desc2", "Desc3"};
                      #endif

                      How to split the definition and definition of the above.

                      Regds,
                      Chinthan EP


                      lars.uffmann@rw th-aachen.de wrote:
                      Michiel.Salters @tomtom.com schrieb:
                      This has nothing to do with #ifdef, which is a preprocessor command.
                      It works only at compile time, and skips every second defintion of 'test'
                      *in a single .cpp*, not across .cpp's. As the compiler works on single
                      .cpp's it won't notice that.
                      >
                      Woohoo - I see light in the dark! Finally the explanation I've been
                      waiting for :) To be honest, I suspected something like this, because
                      the compiler creates libraries for each cpp file separately, so the
                      linker would spot multiple declarations of the variable, but in that
                      case the sense of the preprocessor commands did not occur to me - I
                      never realized it was only to skip further definitions within the same
                      cpp-File.
                      >
                      Thanks for clearing this up! :)
                      And to all the others that helped solving the problem!
                      >
                      Regards,
                      >
                      Lars

                      Comment

                      • Ian Collins

                        #12
                        Re: How to avoid multiple definition of a variable by multiple inclusionof a header file

                        chinthanep@gmai l.com wrote:
                        Hi,
                        >
                        In my implementation, it is like
                        >
                        #ifndef TEST
                        #define TEST
                        const char* strDescriptions[] = {"Desc1", "Desc2", "Desc3"};
                        #endif
                        >
                        How to split the definition and definition of the above.
                        >
                        First, please don't top-post on Usenet, your reply belongs below or
                        interleaved with the post you are replying to.

                        to split, declare the variable in a header and define in once and once
                        only in a source module.

                        In test.h:

                        extern const char* strDescriptions[];

                        in somefile.cc:

                        const char* strDescriptions[] = {"Desc1", "Desc2", "Desc3"};

                        --
                        Ian Collins.

                        Comment

                        Working...