non static variables in a namespace (in .h) ?

Discussion in 'C++' started by vthomasset@gmail.com, Mar 7, 2007.

  1. Guest

    Hi,

    Sorry for the bad subject, but i couldn't figure a better one.

    I would like to understand why a variable declared non static in a
    header causes multiple symbol definitions (if included in different
    compilation units) while the same declaration in a namespace does not.

    Also, what is the correct way to declare a scoped variable in a
    header ? Using extern and declaring it in a separate compilation
    unit ?

    Thank you,
    Vincent
     
    , Mar 7, 2007
    #1
    1. Advertising

  2. John Ratliff Guest

    wrote:
    > Hi,
    >
    > Sorry for the bad subject, but i couldn't figure a better one.
    >
    > I would like to understand why a variable declared non static in a
    > header causes multiple symbol definitions (if included in different
    > compilation units) while the same declaration in a namespace does not.


    Could you show me an example, cause if you define a variable twice in
    the same namespace, you should get multiple symbol definitions and
    linker errors.

    Did you mean you can define the same variable in different namespaces?
    That's fine, of course.

    >
    > Also, what is the correct way to declare a scoped variable in a
    > header ? Using extern and declaring it in a separate compilation
    > unit ?


    If you have to put the definition in a namespace in a header included in
    multiple compilation units, then you should declare it extern and define
    it in a single compilation unit.

    ex:

    myhdr.hh

    #ifndef MYHDR_HH_
    #define MYHDR_HH_

    namespace myns {
    extern int myvar;
    }

    #endif

    main.cc

    #include "myhdr.hh"

    int myns::myvar;

    int main() {
    myns::myvar = 6;
    }

    aux.cc

    #include "myhdr.hh"

    void myfcn() {
    myns::myvar = 10;
    }

    --John Ratliff
     
    John Ratliff, Mar 7, 2007
    #2
    1. Advertising

  3. wrote:
    > Sorry for the bad subject, but i couldn't figure a better one.
    >
    > I would like to understand why a variable declared non static in a
    > header causes multiple symbol definitions (if included in different
    > compilation units) while the same declaration in a namespace does not.


    I don't believe that the second part of this statement is correct.
    Are you sure about "the same declaration"?

    Anyway, an object that is not const and is not explicitly declared
    'static' has _external_ linkage, IOW its name is visible from other
    translation units. If you define (if the declaration does not have
    'extern' specifier, it's a definition) objects with the same name
    in more than one translation unit, it's a violation of the ODR. You
    usually get the error from the linker who is the last to check the
    ODR when linking different TUs together.

    If you declare the object 'static', its name is hidden from other TU
    (not extern), the term is that the name has _internal_ linkage. That
    way you can have objects named the same in different TUs.

    > Also, what is the correct way to declare a scoped variable in a
    > header ?


    "Scoped"? What does that mean? Any variable is scoped, IOW every
    variable has its scope.

    > Using extern and declaring it in a separate compilation
    > unit ?


    There are variations on the theme, but they all essentially lead to
    the same: declaration is available in every TU, and the definition
    exist only in one TU.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 7, 2007
    #3
  4. John Ratliff wrote:
    > wrote:
    >> Hi,
    >>
    >> Sorry for the bad subject, but i couldn't figure a better one.
    >>
    >> I would like to understand why a variable declared non static in a
    >> header causes multiple symbol definitions (if included in different
    >> compilation units) while the same declaration in a namespace does
    >> not.

    >
    > Could you show me an example, cause if you define a variable twice in
    > the same namespace, you should get multiple symbol definitions and
    > linker errors.
    >
    > Did you mean you can define the same variable in different namespaces?
    > That's fine, of course.


    I just thought of what it could be: anonymous namespaces. But that
    falls under "different" category, of course, only the OP didn't think
    of it that way, most likely.

    > [..]


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 7, 2007
    #4
  5. Guest

    On 7 mar, 19:49, "Victor Bazarov" <> wrote:
    > wrote:
    > > I would like to understand why a variable declared non static in a
    > > header causes multiple symbol definitions (if included in different
    > > compilation units) while the same declaration in a namespace does not.

    >
    > I don't believe that the second part of this statement is correct.
    > Are you sure about "the same declaration"?


    My example comes from some software i use. In the main include file,
    it declares a
    bunch of strings as in the following:

    namespace x {
    const std::string s1 = "txt1";
    const std::string s2 = "txt2";
    }

    and the software compiles and runs just fine. When i saw this it
    struck as being strange (that it didn't cause link time error), so i
    just added a simple test string declaration outside of the namespace
    and, of course, got a bunch of 'redeclared symbol' messages at link
    time.

    > Anyway, an object that is not const and is not explicitly declared
    > 'static' has _external_ linkage, IOW its name is visible from other
    > translation units. If you define (if the declaration does not have
    > 'extern' specifier, it's a definition) objects with the same name
    > in more than one translation unit, it's a violation of the ODR. You
    > usually get the error from the linker who is the last to check the
    > ODR when linking different TUs together.


    These strings are const. Does it make any difference ?

    > "Scoped"? What does that mean? Any variable is scoped, IOW every
    > variable has its scope.


    I meant in a namespace... sorry.

    > There are variations on the theme, but they all essentially lead to
    > the same: declaration is available in every TU, and the definition
    > exist only in one TU.


    OK, so being in a namespace does not change the linkage type in any
    way ?

    Vincent
     
    , Mar 7, 2007
    #5
  6. Guest

    On 7 mar, 19:48, John Ratliff <> wrote:
    > wrote:
    > Could you show me an example, cause if you define a variable twice in
    > the same namespace, you should get multiple symbol definitions and
    > linker errors.


    See my response to Victor Bazarow. I can give a link to the header
    file on source control if you would like to see the real code, but
    it's really as plain as i said (though the variables are const).

    > Did you mean you can define the same variable in different namespaces?
    > That's fine, of course.


    No, i meant in the same namespace.

    > If you have to put the definition in a namespace in a header included in
    > multiple compilation units, then you should declare it extern and define
    > it in a single compilation unit.


    <snip example code>

    OK, this is how i understand it, so i don't understand why it works
    correctly in this other software.

    Vincent
     
    , Mar 7, 2007
    #6
  7. wrote:
    > On 7 mar, 19:49, "Victor Bazarov" <> wrote:
    >> wrote:
    >>> I would like to understand why a variable declared non static in a
    >>> header causes multiple symbol definitions (if included in different
    >>> compilation units) while the same declaration in a namespace does
    >>> not.

    >>
    >> I don't believe that the second part of this statement is correct.
    >> Are you sure about "the same declaration"?

    >
    > My example comes from some software i use. In the main include file,
    > it declares a
    > bunch of strings as in the following:
    >
    > namespace x {
    > const std::string s1 = "txt1";
    > const std::string s2 = "txt2";
    > }


    So, have you tried doing the same without the namespace? Does it
    make an iota of difference (except for the s1 and s2 name lookup)?

    > and the software compiles and runs just fine. When i saw this it
    > struck as being strange (that it didn't cause link time error), so i
    > just added a simple test string declaration outside of the namespace
    > and, of course, got a bunch of 'redeclared symbol' messages at link
    > time.


    Nothing strange. Objects are 'const', they have internal linkage.

    >
    >> Anyway, an object that is not const and is not explicitly declared
    >> 'static' has _external_ linkage, IOW its name is visible from other
    >> translation units. If you define (if the declaration does not have
    >> 'extern' specifier, it's a definition) objects with the same name
    >> in more than one translation unit, it's a violation of the ODR. You
    >> usually get the error from the linker who is the last to check the
    >> ODR when linking different TUs together.

    >
    > These strings are const. Does it make any difference ?


    Absodamnlutely.

    >> "Scoped"? What does that mean? Any variable is scoped, IOW every
    >> variable has its scope.

    >
    > I meant in a namespace... sorry.


    Well, those that are "not in a namespace" are actually *in* the
    _global_ namespace. The prefix for finding those is '::'. E.g.

    int a = 0;
    int main() {
    double a = 3.14159;
    return ::a; // note the ::
    }

    There are two 'a' objects here, one has global namespace scope,
    the other has 'main' function scope.

    >> There are variations on the theme, but they all essentially lead to
    >> the same: declaration is available in every TU, and the definition
    >> exist only in one TU.

    >
    > OK, so being in a namespace does not change the linkage type in any
    > way ?


    Nope.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 7, 2007
    #7
  8. Guest

    On 7 mar, 20:18, wrote:
    > and the software compiles and runs just fine. When i saw this it
    > struck as being strange (that it didn't cause link time error), so i
    > just added a simple test string declaration outside of the namespace
    > and, of course, got a bunch of 'redeclared symbol' messages at link
    > time.


    Hmmm, sorry, i just realized that i declared a non const string
    outside
    the namespace (which caused the error). If declared const, i don't get
    a linking error, so it appears my question is actually about the const
    keyword rather than on being in a namespace.
     
    , Mar 7, 2007
    #8
  9. wrote:
    > On 7 mar, 20:18, wrote:
    >> and the software compiles and runs just fine. When i saw this it
    >> struck as being strange (that it didn't cause link time error), so i
    >> just added a simple test string declaration outside of the namespace
    >> and, of course, got a bunch of 'redeclared symbol' messages at link
    >> time.

    >
    > Hmmm, sorry, i just realized that i declared a non const string
    > outside
    > the namespace (which caused the error). If declared const, i don't get
    > a linking error, so it appears my question is actually about the const
    > keyword rather than on being in a namespace.


    Yep. 'const' without "extern" gives the object internal linkage.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 7, 2007
    #9
  10. Guest

    On 7 mar, 20:47, "Victor Bazarov" <> wrote:
    > wrote:
    > > namespace x {
    > > const std::string s1 = "txt1";
    > > const std::string s2 = "txt2";
    > > }

    >
    > So, have you tried doing the same without the namespace? Does it
    > make an iota of difference (except for the s1 and s2 name lookup)?


    I have now. :)

    > Nothing strange. Objects are 'const', they have internal linkage.


    Thanks a lot for your explanations.

    Vincent
     
    , Mar 7, 2007
    #10
    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. Sehcra
    Replies:
    3
    Views:
    406
  2. Neviton
    Replies:
    9
    Views:
    463
    Alf P. Steinbach
    Sep 17, 2007
  3. Alan Woodland
    Replies:
    12
    Views:
    542
    Marco Manfredini
    Nov 22, 2007
  4. Dobedani
    Replies:
    0
    Views:
    380
    Dobedani
    Jul 15, 2008
  5. rickman
    Replies:
    5
    Views:
    428
    rickman
    Mar 30, 2013
Loading...

Share This Page