const objects at module level

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • newbarker@gmail.com

    #1

    const objects at module level

    Hello,

    Very basic question here. If I have the following constants declared
    in a.cpp and in b.cpp, would there be any possibility of duplicate
    symbols?:

    a.cpp
    --------
    #include <string>

    const int TheNumber = 1;
    const std::string TheString("Hell o");

    b.cpp
    --------
    #include <string>

    const int TheNumber = 1;
    const std::string TheString("Hell o");

    Are they not inserted into the symbol table? Previously, I've put
    these into an unnamed namespace to be sure but I'm code reviewing
    others' code and they're questioning the need for an anonymous
    namespace, and I suspect they're correct based on my small test
    programs with VC++.

    Thanks,

    Pete
  • Jeff Schwab

    #2
    Re: const objects at module level

    newbarker@gmail .com wrote:
    Hello,
    >
    Very basic question here. If I have the following constants declared
    in a.cpp and in b.cpp, would there be any possibility of duplicate
    symbols?:
    >
    a.cpp
    --------
    #include <string>
    >
    const int TheNumber = 1;
    const std::string TheString("Hell o");
    >
    b.cpp
    --------
    #include <string>
    >
    const int TheNumber = 1;
    const std::string TheString("Hell o");
    >
    Are they not inserted into the symbol table? Previously, I've put
    these into an unnamed namespace to be sure but I'm code reviewing
    others' code and they're questioning the need for an anonymous
    namespace, and I suspect they're correct based on my small test
    programs with VC++.
    C++ constants at global scope have internal linkage by default. This is
    different from C, where they have external linkage. The first reason
    that comes to mind for this difference is so that C++ constants (with
    proper static types) can effectively replace C-style preprocessor
    constants (#define MAX 42).

    Functions and non-const variables declared at global scope have default
    external linkage in both C and C++.

    FWIW, this surprised me, too. I group these constants into unnamed
    namespaces as well, and probably will continue to do so, for reasons
    vaguely akin to why I always put curly braces around loop bodies, even
    when technically unnecessary.

    Comment

    • newbarker@gmail.com

      #3
      Re: const objects at module level

      On Mar 13, 3:12 pm, Jeff Schwab <j...@schwabcen ter.comwrote:
      newbar...@gmail .com wrote:
      Hello,
      >
      Very basic question here. If I have the following constants declared
      in a.cpp and in b.cpp, would there be any possibility of duplicate
      symbols?:
      >
      a.cpp
      --------
      #include <string>
      >
      const int TheNumber = 1;
      const std::string TheString("Hell o");
      >
      b.cpp
      --------
      #include <string>
      >
      const int TheNumber = 1;
      const std::string TheString("Hell o");
      >
      Are they not inserted into the symbol table? Previously, I've put
      these into an unnamed namespace to be sure but I'm code reviewing
      others' code and they're questioning the need for an anonymous
      namespace, and I suspect they're correct based on my small test
      programs with VC++.
      >
      C++ constants at global scope have internal linkage by default.  This is
      different from C, where they have external linkage.  The first reason
      that comes to mind for this difference is so that C++ constants (with
      proper static types) can effectively replace C-style preprocessor
      constants (#define MAX 42).
      >
      Functions and non-const variables declared at global scope have default
      external linkage in both C and C++.
      >
      FWIW, this surprised me, too.  I group these constants into unnamed
      namespaces as well, and probably will continue to do so, for reasons
      vaguely akin to why I always put curly braces around loop bodies, even
      when technically unnecessary.- Hide quoted text -
      >
      - Show quoted text -
      Jeff,

      Thanks for the reply. I've also found Stroustrup say the same it's ok
      in CPPPL3E section 9.2. (but he doesn't point out the difference with
      C).

      Pete

      Comment

      • James Kanze

        #4
        Re: const objects at module level

        On Mar 13, 4:12 pm, Jeff Schwab <j...@schwabcen ter.comwrote:
        newbar...@gmail .com wrote:
        Very basic question here. If I have the following constants
        declared in a.cpp and in b.cpp, would there be any
        possibility of duplicate symbols?:
        a.cpp
        --------
        #include <string>
        const int TheNumber = 1;
        const std::string TheString("Hell o");
        b.cpp
        --------
        #include <string>
        const int TheNumber = 1;
        const std::string TheString("Hell o");
        Are they not inserted into the symbol table? Previously,
        I've put these into an unnamed namespace to be sure but I'm
        code reviewing others' code and they're questioning the need
        for an anonymous namespace, and I suspect they're correct
        based on my small test programs with VC++.
        C++ constants at global scope have internal linkage by
        default. This is different from C, where they have external
        linkage. The first reason that comes to mind for this
        difference is so that C++ constants (with proper static types)
        can effectively replace C-style preprocessor constants
        (#define MAX 42).
        Which really isn't much of a reason, since you could aways write
        "static const int ...", if that's what you wanted.
        Functions and non-const variables declared at global scope
        have default external linkage in both C and C++.
        FWIW, this surprised me, too. I group these constants into
        unnamed namespaces as well, and probably will continue to do
        so, for reasons vaguely akin to why I always put curly braces
        around loop bodies, even when technically unnecessary.
        The case where it's really surprising is with regards to
        templates. Something like "template< int const* PI ..." can't
        be instantiated with the address of TheNumber, above. You have
        to define it:
        extern int const TheNumber = 1 ;
        (Put it in an anonymous namespace, and you've effectively used
        "extern" to define a local variable.)

        --
        James Kanze (GABI Software) email:james.kan ze@gmail.com
        Conseils en informatique orientée objet/
        Beratung in objektorientier ter Datenverarbeitu ng
        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

        Comment

        • Jeff Schwab

          #5
          Re: const objects at module level

          James Kanze wrote:
          On Mar 13, 4:12 pm, Jeff Schwab <j...@schwabcen ter.comwrote:
          >newbar...@gmai l.com wrote:
          >>Very basic question here. If I have the following constants
          >>declared in a.cpp and in b.cpp, would there be any
          >>possibility of duplicate symbols?:
          >
          >>a.cpp
          >>--------
          >>#include <string>
          >
          >>const int TheNumber = 1;
          >>const std::string TheString("Hell o");
          >
          >>b.cpp
          >>--------
          >>#include <string>
          >
          >>const int TheNumber = 1;
          >>const std::string TheString("Hell o");
          >
          >>Are they not inserted into the symbol table? Previously,
          >>I've put these into an unnamed namespace to be sure but I'm
          >>code reviewing others' code and they're questioning the need
          >>for an anonymous namespace, and I suspect they're correct
          >>based on my small test programs with VC++.
          >
          >C++ constants at global scope have internal linkage by
          >default. This is different from C, where they have external
          >linkage. The first reason that comes to mind for this
          >difference is so that C++ constants (with proper static types)
          >can effectively replace C-style preprocessor constants
          >(#define MAX 42).
          >
          Which really isn't much of a reason, since you could aways write
          "static const int ...", if that's what you wanted.
          True. Or use unnamed namespaces.
          >Functions and non-const variables declared at global scope
          >have default external linkage in both C and C++.
          >
          >FWIW, this surprised me, too. I group these constants into
          >unnamed namespaces as well, and probably will continue to do
          >so, for reasons vaguely akin to why I always put curly braces
          >around loop bodies, even when technically unnecessary.
          >
          The case where it's really surprising is with regards to
          templates. Something like "template< int const* PI ..." can't
          be instantiated with the address of TheNumber, above. You have
          to define it:
          extern int const TheNumber = 1 ;
          (Put it in an anonymous namespace, and you've effectively used
          "extern" to define a local variable.)
          That does seem odd. Do you know of a better reason for the default
          internal linkage of global-scope constants? I do not.

          Comment

          Working...