Const objects defined in headers

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

    #1

    Const objects defined in headers

    Hi, All:

    I read the following passage from a book:

    "There are three exceptions to the rule that headers should not contain
    definitions: classes, const objects whose value is known at compile
    time, and inline functions are all defined in headers. "

    Can someone explain to me why some of the const objects must be defined
    in the header file?

    Thanks in advance for the help

    --Rui

  • Alf P. Steinbach

    #2
    Re: Const objects defined in headers

    * Rui.Hu719@gmail .com:
    >
    I read the following passage from a book:
    >
    "There are three exceptions to the rule that headers should not contain
    definitions: classes, const objects whose value is known at compile
    time, and inline functions are all defined in headers. "
    >
    Can someone explain to me why some of the const objects must be defined
    in the header file?
    No, because (1) that's not what the quoted passage says, and (2) the C++
    standard does not assume the existence of files or a file system.

    As a practical matter you can define const objects in a header file.

    That doesn't mean you must.

    As a formal matter you can define anything in a header file.

    That doesn't mean you must or should.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?

    Comment

    • Rui.Hu719@gmail.com

      #3
      Re: Const objects defined in headers

      Hi, Alf:

      Thanks a lot for the information, I am still a little confusing here,
      bear with me since I am new to C++. Here is the complete section from
      the book, basically it is saying that you should never put definitions
      for variables or functions in header files since headers are included
      in multiple source files, but for some reason, the definition for some
      constants should in the header file.

      from the book, C++ Primer:

      "When designing a header it is essential to remember the difference
      between definitions, which may only occur once, and declarations, which
      may occur multiple times, Because headers are included in multiple
      source files, they should not contain definitions of variables or
      functions."

      "There are three exceptions to the rule that headers should not contain
      definitions: classes, const objects whose value is known at compile
      time, and inline functions are all defined in headers. These entities
      may be defined in more than one source file as long as the definitions
      in each file are exactly the same.

      These entities are defined in headers because the compiler needs their
      definitions (not just declarations) to generate code. For example, to
      generate code that defines or uses objects of a class type, the
      compiler needs to know what data members make up that type. It also
      needs to know what operations can be performed on these objects. The
      class definition provides the needed information. That const objects
      are defined in a header may require a bit more explanation."

      Recall that by default a const variable (Section 2.4, p. 57) is local
      to the file in which it is defined. As we shall now see, the reason for
      this default is to allow const variables to be defined in header files.

      In C++ there are places where constant expression (Section 2.7, p. 62)
      is required. For example, the initializer of an enumerator must be a
      constant expression. We'll see other cases that require constant
      expressions in later chapters.

      Generally speaking, a constant expression is an expression that the
      compiler can evaluate at compile-time. A const variable of integral
      type may be a constant expression when it is itself initialized from a
      constant expression. However, for the const to be a constant
      expression, the initializer must be visible to the compiler. To allow
      multiple files to use the same constant value, the const and its
      initializer must be visible in each file. To make the initializer
      visible, we normally define such consts inside a header file. That way
      the compiler can see the initializer whenever the const is used.

      However, there can be only one definition (Section 2.3.5, p. 52) for
      any variable in a C++ program. A definition allocates storage; all uses
      of the variable must refer to the same storage. Because, by default,
      const objects are local to the file in which they are defined, it is
      legal to put their definition in a header file.

      There is one important implication of this behavior. When we define a
      const in a header file, every source file that includes that header has
      its own const variable with the same name and value.

      When the const is initialized by a constant expression, then we are
      guaranteed that all the variables will have the same value. Moreover,
      in practice, most compilers will replace any use of such const
      variables by their corresponding constant expression at compile time.
      So, in practice, there won't be any storage used to hold const
      variables that are initialized by constant expressions.

      When a const is initialized by a value that is not a constant
      expression, then it should not be defined in header file. Instead, as
      with any other variable, the const should be defined and initialized in
      a source file. An extern declaration for that const should be made in
      the header, enabling multiple files to share that variable.

      I don't really understand the explanation offered by the book.

      Thanks again for the help

      --Rui




      Alf P. Steinbach wrote:
      * Rui.Hu719@gmail .com:

      I read the following passage from a book:

      "There are three exceptions to the rule that headers should not contain
      definitions: classes, const objects whose value is known at compile
      time, and inline functions are all defined in headers. "

      Can someone explain to me why some of the const objects must be defined
      in the header file?
      >
      No, because (1) that's not what the quoted passage says, and (2) the C++
      standard does not assume the existence of files or a file system.
      >
      As a practical matter you can define const objects in a header file.
      >
      That doesn't mean you must.
      >
      As a formal matter you can define anything in a header file.
      >
      That doesn't mean you must or should.
      >
      --
      A: Because it messes up the order in which people normally read text.
      Q: Why is it such a bad thing?
      A: Top-posting.
      Q: What is the most annoying thing on usenet and in e-mail?

      Comment

      • Alf P. Steinbach

        #4
        Re: Const objects defined in headers

        * Rui.Hu719@gmail .com:
        [top-posting]
        Please don't top-post in this group. See the FAQ. Corrected.


        * Rui.Hu719@gmail .com:
        [snip]
        >
        I don't really understand the explanation offered by the book.
        C++ has a "one definition rule" (often referred to as the "ODR").

        In practical terms the ODR is essentially that the linker should only be
        presented with /one/ global definition of something -- whatever it is
        -- unless that something is

        * an 'inline' function, or

        * a templated thing,

        in which case the linker will simply choose one of the definitions it
        encounters, and blithely assume that all others are exactly the same.

        The ODR also holds within a translation unit, but (1) that's not a
        problem that occurs very often in practice, and (2) within a translation
        unit an ODR violation such as

        void foo() {} // 1st definition
        void foo() {} // 2nd definition, doesn't matter that it's the same

        will be detected by the compiler.

        Now, when you for example define a not-'inline' function foo in a header
        file, and include that header file in more than one translation unit,
        then each translation unit will generate one definition of foo, and the
        linker will be presented with multiple global definitions of foo, in
        violation of the ODR, and most linkers will then complain.

        Here I've used the word "global" for definitions that are accessible and
        used throughout the program, as opposed to accessible just locally
        within a translation unit. The C++ terms are, respectively, "extern
        linkage" for global access, and "internal linkage" for access restricted
        to the relevant translation unit. 'const' objects that are declared
        outside functions and classes have internal linkage by default, so the
        ODR does not apply except if you define the same one more than once in
        the translation unit's own code. Therefore, you can freely define
        'const' objects in header files, as a practical matter. However,
        non-'const' objects that are declared outside functions and classes have
        external linkage by default, so the ODR does apply. Include that header
        file in more than translation unit and the linker will be unhappy.

        --
        A: Because it messes up the order in which people normally read text.
        Q: Why is it such a bad thing?
        A: Top-posting.
        Q: What is the most annoying thing on usenet and in e-mail?

        Comment

        • Rui.Hu719@gmail.com

          #5
          Re: Const objects defined in headers


          Alf P. Steinbach wrote:
          * Rui.Hu719@gmail .com:
          [top-posting]
          >
          Please don't top-post in this group. See the FAQ. Corrected.
          >
          >
          * Rui.Hu719@gmail .com:
          [snip]

          I don't really understand the explanation offered by the book.
          >
          C++ has a "one definition rule" (often referred to as the "ODR").
          >
          In practical terms the ODR is essentially that the linker should only be
          presented with /one/ global definition of something -- whatever it is
          -- unless that something is
          >
          * an 'inline' function, or
          >
          * a templated thing,
          >
          in which case the linker will simply choose one of the definitions it
          encounters, and blithely assume that all others are exactly the same.
          >
          The ODR also holds within a translation unit, but (1) that's not a
          problem that occurs very often in practice, and (2) within a translation
          unit an ODR violation such as
          >
          void foo() {} // 1st definition
          void foo() {} // 2nd definition, doesn't matter that it's the same
          >
          will be detected by the compiler.
          >
          Now, when you for example define a not-'inline' function foo in a header
          file, and include that header file in more than one translation unit,
          then each translation unit will generate one definition of foo, and the
          linker will be presented with multiple global definitions of foo, in
          violation of the ODR, and most linkers will then complain.
          >
          Here I've used the word "global" for definitions that are accessible and
          used throughout the program, as opposed to accessible just locally
          within a translation unit. The C++ terms are, respectively, "extern
          linkage" for global access, and "internal linkage" for access restricted
          to the relevant translation unit. 'const' objects that are declared
          outside functions and classes have internal linkage by default, so the
          ODR does not apply except if you define the same one more than once in
          the translation unit's own code. Therefore, you can freely define
          'const' objects in header files, as a practical matter. However,
          non-'const' objects that are declared outside functions and classes have
          external linkage by default, so the ODR does apply. Include that header
          file in more than translation unit and the linker will be unhappy.
          >
          Thanks a lot for the explanation




          A: Because it messes up the order in which people normally read text.
          Q: Why is it such a bad thing?
          A: Top-posting.
          Q: What is the most annoying thing on usenet and in e-mail?

          Comment

          Working...