Header problems

Discussion in 'C Programming' started by gamehack, Feb 15, 2006.

  1. gamehack

    gamehack Guest

    Hi all,

    Let me describe the problem. I've a header file util.h which contains
    the following:
    #ifndef UTIL_H_
    #define UTIL_H_

    const char DEF_TITLE[] = "My Title";

    int num_chars(int num);
    char* get_default_title(void);

    #endif /* UTIL_H_ */

    When I include the header from two or more files in complains that
    DEF_TITLE is defined more than once: "multiple definition of
    `DEF_TITLE`" is printed for both files which use DEF_TITLE. I cannot
    understand why this happens since I've put the header guards. Platform
    is MinGW 3.4.2 & Win XP Pro.

    Regards
     
    gamehack, Feb 15, 2006
    #1
    1. Advertising

  2. gamehack

    osmium Guest

    "gamehack" writes:

    > Let me describe the problem. I've a header file util.h which contains
    > the following:
    > #ifndef UTIL_H_
    > #define UTIL_H_
    >
    > const char DEF_TITLE[] = "My Title";


    Header guards do not protect against multiple definitions. Each program
    segment that includes this header gets exactly one definition for DEF_TITLE.
    There should only be *type* definitions or variable *declarations* in a
    header.

    Change it to external (q.v.) which will demote it to a declaration. Put a
    definition in one of the files where it makes sense.

    >
    > int num_chars(int num);
    >
    > char* get_default_title(void);
    >
    > #endif /* UTIL_H_ */
    >
    > When I include the header from two or more files in complains that
    > DEF_TITLE is defined more than once: "multiple definition of
    > `DEF_TITLE`" is printed for both files which use DEF_TITLE. I cannot
    > understand why this happens since I've put the header guards. Platform
    > is MinGW 3.4.2 & Win XP Pro.
    >
    > Regards
    >
     
    osmium, Feb 15, 2006
    #2
    1. Advertising

  3. gamehack

    Michael Mair Guest

    gamehack schrieb:
    > Hi all,
    >
    > Let me describe the problem. I've a header file util.h which contains
    > the following:
    > #ifndef UTIL_H_
    > #define UTIL_H_
    >
    > const char DEF_TITLE[] = "My Title";


    DEF_TITLE is a file scope identifier with external linkage.
    It must not be used more than once as such in the whole
    programme. So, if you #include "util.h" in more than one
    translation unit, this thing breaks.
    >
    > int num_chars(int num);
    > char* get_default_title(void);
    >
    > #endif /* UTIL_H_ */
    >
    > When I include the header from two or more files in complains that
    > DEF_TITLE is defined more than once: "multiple definition of
    > `DEF_TITLE`" is printed for both files which use DEF_TITLE. I cannot
    > understand why this happens since I've put the header guards.


    Header guards protect against
    -- a.h --
    #include "b.h"
    ---------
    -- b.h --
    #include "a.h"
    ---------
    and multiple definitions of types.

    Consider

    -- util.h --
    #ifndef UTIL_H_
    #define UTIL_H_

    extern const char *DEF_TITLE;

    int num_chars(int num);
    char* get_default_title(void);

    #endif /* UTIL_H_ */
    ------------
    -- util.c --
    #include "util.h"

    const char *DEF_TITLE = "My Title";

    .....

    ------------

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Feb 15, 2006
    #3
  4. gamehack

    Pedro Graca Guest

    gamehack wrote:
    > Let me describe the problem. I've a header file util.h which contains
    > the following:
    > #ifndef UTIL_H_
    > #define UTIL_H_
    >
    > const char DEF_TITLE[] = "My Title";


    Why not

    #define DEF_TITLE "My Title" /* no semicolon */

    > int num_chars(int num);
    > char* get_default_title(void);
    >
    > #endif /* UTIL_H_ */


    And then use it in your program as a constant string

    /* ... */
    char title1[] = DEF_TITLE;
    char *title2 = NULL;
    /* ... including allocating space for title2 ... */
    strcpy(title2, DEF_TITLE);
    /* ... */
    printf("Title: %s\n", title2 ? title2 : DEF_TITLE);
    /* ... */

    --
    If you're posting through Google read <http://cfaj.freeshell.org/google>
     
    Pedro Graca, Feb 15, 2006
    #4
  5. gamehack

    Michael Mair Guest

    Pedro Graca schrieb:
    > gamehack wrote:
    >
    >>Let me describe the problem. I've a header file util.h which contains
    >>the following:
    >>#ifndef UTIL_H_
    >>#define UTIL_H_
    >>
    >>const char DEF_TITLE[] = "My Title";

    >
    >
    > Why not
    >
    > #define DEF_TITLE "My Title" /* no semicolon */
    >
    >
    >>int num_chars(int num);
    >>char* get_default_title(void);
    >>
    >>#endif /* UTIL_H_ */

    >
    >
    > And then use it in your program as a constant string
    >
    > /* ... */
    > char title1[] = DEF_TITLE;
    > char *title2 = NULL;
    > /* ... including allocating space for title2 ... */
    > strcpy(title2, DEF_TITLE);
    > /* ... */
    > printf("Title: %s\n", title2 ? title2 : DEF_TITLE);
    > /* ... */


    This
    - does not protect you against inadvertently trying
    to modify DEF_TITLE
    - potentially wastes storage if "My Title" is stored
    multiple times (e.g. once per translation unit, once
    per function, once per use...)

    String literals should be used with care.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Feb 16, 2006
    #5
  6. On Wed, 15 Feb 2006 10:24:38 -0800, "osmium" <>
    wrote:

    > "gamehack" writes:
    >
    > > Let me describe the problem. I've a header file util.h which contains
    > > the following:
    > > #ifndef UTIL_H_
    > > #define UTIL_H_
    > >
    > > const char DEF_TITLE[] = "My Title";

    >
    > Header guards do not protect against multiple definitions. Each program
    > segment that includes this header gets exactly one definition for DEF_TITLE.


    More specifically, each 'translation unit' = source file + includes.

    > There should only be *type* definitions or variable *declarations* in a
    > header.
    >
    > Change it to external (q.v.) which will demote it to a declaration. Put a
    > definition in one of the files where it makes sense.
    >

    Just adding 'extern' (not 'external', and not replacing anything
    already there) to a declaration with an initializer doesn't help; it's
    still a definition. You need to declare with extern and no
    initializer, and then (as you say) define in one t.u.

    It may be a problem (or not) that in that scheme the declaration
    extern const char DEF_TITLE [] ;
    has unknown bound/size, whereas with the initializer it has a known
    size from the initial value even though not explicitly written. If
    this matters you can duplicate the value in each t.u. as
    static const char DEF_TITLE [] = "Value";
    (It is even possible, and certainly permitted though not required,
    that the implementation might be clever enough to merge these.)


    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Feb 27, 2006
    #6
    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. Newsgroup - Ann
    Replies:
    4
    Views:
    716
    lilburne
    Nov 2, 2003
  2. John Smith

    Header files included in header files

    John Smith, Jul 21, 2004, in forum: C Programming
    Replies:
    18
    Views:
    611
    Jack Klein
    Jul 24, 2004
  3. Replies:
    3
    Views:
    1,309
    Walter Roberson
    May 1, 2006
  4. Bit byte
    Replies:
    1
    Views:
    658
    benben
    Apr 19, 2006
  5. mlt
    Replies:
    2
    Views:
    853
    Jean-Marc Bourguet
    Jan 31, 2009
Loading...

Share This Page