A question about ifndef

Discussion in 'C Programming' started by QQ, Nov 2, 2005.

  1. QQ

    QQ Guest

    I am reading a book. It introduces ifndef as the following:
    --------------------------------------------------------------------------------------
    Look at the following code:
    #ifndef _CONST_H_INCLUDED_
    /* define constants */
    #define _CONST_H_INCLUDED_
    #endif /* _CONST_H_INCLUDED_ */

    When const.h is included, it defines the symbol _CONST_H_INCLUDED_. If
    that symbol is already defined (because the file was included earlier),
    the #ifndef conditional hides all defines so they don't cause
    trouble.
    --------------------------------------------------------------------------------------

    I don't quite understand why we need to define a symbol in this way.
    What does it tell?

    Anyone can explain to me?

    Thanks a lot!
    QQ, Nov 2, 2005
    #1
    1. Advertising

  2. QQ

    Default User Guest

    QQ wrote:

    > I am reading a book. It introduces ifndef as the following:
    > ----------------------------------------------------------------------
    > ---------------- Look at the following code:
    > #ifndef _CONST_H_INCLUDED_
    > /* define constants */
    > #define _CONST_H_INCLUDED_
    > #endif /* _CONST_H_INCLUDED_ */
    >
    > When const.h is included, it defines the symbol _CONST_H_INCLUDED_. If
    > that symbol is already defined (because the file was included
    > earlier), the #ifndef conditional hides all defines so they don't
    > cause trouble.
    > ----------------------------------------------------------------------
    > ----------------
    >
    > I don't quite understand why we need to define a symbol in this way.
    > What does it tell?


    It prevents the declarations from the header being included more than
    once in the same translation unit.



    Brian
    Default User, Nov 2, 2005
    #2
    1. Advertising

  3. In article <>,
    QQ <> wrote:
    >I am reading a book. It introduces ifndef as the following:


    >Look at the following code:


    >#ifndef _CONST_H_INCLUDED_
    >/* define constants */
    >#define _CONST_H_INCLUDED_
    >#endif /* _CONST_H_INCLUDED_ */


    >When const.h is included, it defines the symbol _CONST_H_INCLUDED_. If
    >that symbol is already defined (because the file was included earlier),
    >the #ifndef conditional hides all defines so they don't cause
    >trouble.


    >I don't quite understand why we need to define a symbol in this way.
    >What does it tell?


    You usually only need to include any given header file once per
    translation unit: after that, the macros and types and function
    prototypes that it defines are present in the translation unit and
    you don't need to include them again later.

    But header files usually #include all the header files that they
    specifically depend on, so that the header file will be sure that
    everything it needs will be present.

    This practice -often- leads to instances where a particular header
    file gets included, and then later down in the translation unit,
    something includes it again. That's usually a big waste of compilation
    resources... how many times do you need to #define NULL anyhow?

    To avoid that waste, the convention was adopted that headers that
    only need to be included once, are configured in such a way that
    after the first time they get included, a symbol gets defined, and
    then the next time they get included, the header looks and sees that
    that symbol is already defined and so knows to skip everything it
    would have defined.


    Note: I wouldn't do it the way you show; I would change the order
    slightly, to

    #ifndef _CONST_H_INCLUDED_
    #define _CONST_H_INCLUDED_
    /* define constants */
    #endif /* _CONST_H_INCLUDED_ */

    where the symbol gets defined before the rest of the file gets
    processed. If -somehow- you managed to end up with a loop of #include
    files that got back the original file, then with the order you show,
    on the second processing of the file, the protective symbol would
    not have been defined yet, so the file would get expanded... possibly
    resulting in another loop... But if you define the symbol first,
    then on the second processing of the file, it would just gracefully
    do nothing and continue processing the calling file, eventually
    getting back to the first expansion, at which time the file would
    be expanded exactly once.
    --
    Chocolate is "more than a food but less than a drug" -- RJ Huxtable
    Walter Roberson, Nov 2, 2005
    #3
  4. QQ

    Ben Pfaff Guest

    -cnrc.gc.ca (Walter Roberson) writes:

    > This practice -often- leads to instances where a particular header
    > file gets included, and then later down in the translation unit,
    > something includes it again. That's usually a big waste of compilation
    > resources... how many times do you need to #define NULL anyhow?
    >
    > To avoid that waste, the convention was adopted that headers that
    > only need to be included once, are configured in such a way that
    > after the first time they get included, a symbol gets defined, and
    > then the next time they get included, the header looks and sees that
    > that symbol is already defined and so knows to skip everything it
    > would have defined.


    It's not just for compilation performance. (If it were, then I'd
    probably omit them in my header files, because they're ugly.)
    It's also to avoid compilation errors due to redefinitions:
    structures, unions, and enumerations (and some other kinds of
    entities?) may not be defined more than once.
    --
    Bite me! said C.
    Ben Pfaff, Nov 2, 2005
    #4
  5. QQ

    Ben Pfaff Guest

    "QQ" <> writes:

    > #ifndef _CONST_H_INCLUDED_
    > /* define constants */
    > #define _CONST_H_INCLUDED_
    > #endif /* _CONST_H_INCLUDED_ */


    Identifiers whose names begin with _ followed by a capital letter
    are reserved for all uses.
    --
    Ben Pfaff
    email:
    web: http://benpfaff.org
    Ben Pfaff, Nov 2, 2005
    #5
  6. QQ

    pete Guest

    Ben Pfaff wrote:
    >
    > -cnrc.gc.ca (Walter Roberson) writes:
    >
    > > This practice -often- leads to instances where a particular header
    > > file gets included, and then later down in the translation unit,
    > > something includes it again. That's usually a big waste of compilation
    > > resources... how many times do you need to #define NULL anyhow?
    > >
    > > To avoid that waste, the convention was adopted that headers that
    > > only need to be included once, are configured in such a way that
    > > after the first time they get included, a symbol gets defined, and
    > > then the next time they get included, the header looks and sees that
    > > that symbol is already defined and so knows to skip everything it
    > > would have defined.

    >
    > It's not just for compilation performance. (If it were, then I'd
    > probably omit them in my header files, because they're ugly.)
    > It's also to avoid compilation errors due to redefinitions:
    > structures, unions, and enumerations (and some other kinds of
    > entities?) may not be defined more than once.


    Object definitions and function definitions
    don't belong in header files, do they?

    If declarations which are neither object defintions
    nor function defintions, are declared twice, what's the harm?

    --
    pete
    pete, Nov 3, 2005
    #6
  7. QQ

    Flash Gordon Guest

    pete wrote:
    > Ben Pfaff wrote:


    <snip header guards>

    >>It's not just for compilation performance. (If it were, then I'd
    >>probably omit them in my header files, because they're ugly.)
    >>It's also to avoid compilation errors due to redefinitions:
    >>structures, unions, and enumerations (and some other kinds of
    >>entities?) may not be defined more than once.

    >
    > Object definitions and function definitions
    > don't belong in header files, do they?


    Yes, but I'm sure that is not what Ben was referring to.

    > If declarations which are neither object defintions
    > nor function defintions, are declared twice, what's the harm?


    The harm is that, for example,
    struct fred {int i;};
    struct fred {int i;};
    will not compile. Note that this is defining a struct, but *not*
    defining an object of that struct type.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Nov 3, 2005
    #7
  8. QQ

    pete Guest

    Flash Gordon wrote:
    >
    > pete wrote:
    > > Ben Pfaff wrote:

    >
    > <snip header guards>
    >
    > >>It's not just for compilation performance. (If it were, then I'd
    > >>probably omit them in my header files, because they're ugly.)
    > >>It's also to avoid compilation errors due to redefinitions:
    > >>structures, unions, and enumerations (and some other kinds of
    > >>entities?) may not be defined more than once.

    > >
    > > Object definitions and function definitions
    > > don't belong in header files, do they?

    >
    > Yes, but I'm sure that is not what Ben was referring to.
    >
    > > If declarations which are neither object defintions
    > > nor function defintions, are declared twice, what's the harm?

    >
    > The harm is that, for example,
    > struct fred {int i;};
    > struct fred {int i;};
    > will not compile. Note that this is defining a struct, but *not*
    > defining an object of that struct type.


    My compiler agrees with you,
    but I can't find any words in the standard which call
    struct fred {int i;};
    a definition.

    Got a reference?

    I would describe
    struct fred {int i;};
    as a declaration of a complete struct type.

    So far, I only know of 4 kinds of definitions in a translation unit:
    1 object
    2 function
    3 enum
    4 typedef

    Do I need to add more to the list?

    --
    pete
    pete, Nov 3, 2005
    #8
  9. QQ

    Ben Pfaff Guest

    pete <> writes:

    > Ben Pfaff wrote:
    >> [...on header guards...]
    >> It's also to avoid compilation errors due to redefinitions:
    >> structures, unions, and enumerations (and some other kinds of
    >> entities?) may not be defined more than once.

    >
    > Object definitions and function definitions
    > don't belong in header files, do they?


    Inline function definitions do make sense in header files.


    > If declarations which are neither object defintions
    > nor function defintions, are declared twice, what's the harm?


    You can't declare a given typedef more than once, even if the
    definitions are identical. Similarly for structures, unions, and
    enumerations.

    > Flash Gordon wrote:
    >> The harm is that, for example,
    >> struct fred {int i;};
    >> struct fred {int i;};
    >> will not compile. Note that this is defining a struct, but *not*
    >> defining an object of that struct type.

    >
    > My compiler agrees with you,
    > but I can't find any words in the standard which call
    > struct fred {int i;};
    > a definition.


    If your quibble is with me calling a declaration of a structure a
    "definition", then please consider me corrected. Now, do you
    have a real objection, other than this minor vocabulary issue?

    > Got a reference?


    6.7.2.3 Tags
    Constraints
    1 A specific type shall have its content defined at most once.

    (And wouldn't defining the content of a specific type be a
    "definition" of that type?)
    --
    "In My Egotistical Opinion, most people's C programs should be indented six
    feet downward and covered with dirt." -- Blair P. Houghton
    Ben Pfaff, Nov 3, 2005
    #9
  10. QQ

    pete Guest

    Ben Pfaff wrote:
    >
    > pete <> writes:
    >
    > > Ben Pfaff wrote:
    > >> [...on header guards...]
    > >> It's also to avoid compilation errors due to redefinitions:
    > >> structures, unions, and enumerations (and some other kinds of
    > >> entities?) may not be defined more than once.

    > >
    > > Object definitions and function definitions
    > > don't belong in header files, do they?

    >
    > Inline function definitions do make sense in header files.
    >
    > > If declarations which are neither object defintions
    > > nor function defintions, are declared twice, what's the harm?

    >
    > You can't declare a given typedef more than once, even if the
    > definitions are identical. Similarly for structures, unions, and
    > enumerations.
    >
    > > Flash Gordon wrote:
    > >> The harm is that, for example,
    > >> struct fred {int i;};
    > >> struct fred {int i;};
    > >> will not compile. Note that this is defining a struct, but *not*
    > >> defining an object of that struct type.

    > >
    > > My compiler agrees with you,
    > > but I can't find any words in the standard which call
    > > struct fred {int i;};
    > > a definition.

    >
    > If your quibble is with me calling a declaration of a structure a
    > "definition", then please consider me corrected. Now, do you
    > have a real objection, other than this minor vocabulary issue?
    >
    > > Got a reference?

    >
    > 6.7.2.3 Tags
    > Constraints
    > 1 A specific type shall have its content defined at most once.
    >
    > (And wouldn't defining the content of a specific type be a
    > "definition" of that type?)


    If it is a "definition" of that type,
    then how can I consider you to be corrected?
    Terminology is important to me,
    even if you're better at it than I am.
    If a complete struct declaration is a definition,
    then your original statement,

    > >> It's also to avoid compilation errors due to redefinitions:
    > >> structures, unions, and enumerations (and some other kinds of
    > >> entities?) may not be defined more than once.


    .... is correct and could be shortened to:
    "It's also to avoid compilation errors due to redefinitions."

    --
    pete
    pete, Nov 3, 2005
    #10
  11. >Object definitions and function definitions
    >don't belong in header files, do they?


    typedefs do.

    >If declarations which are neither object defintions
    >nor function defintions, are declared twice, what's the harm?


    If you put the same typedef in twice, compilation fails.

    Gordon L. Burditt
    Gordon Burditt, Nov 3, 2005
    #11
  12. QQ

    pete Guest

    Gordon Burditt wrote:
    >
    > >Object definitions and function definitions
    > >don't belong in header files, do they?

    >
    > typedefs do.
    >
    > >If declarations which are neither object defintions
    > >nor function defintions, are declared twice, what's the harm?

    >
    > If you put the same typedef in twice, compilation fails.


    Can a "definition" be described as the kind of declaration
    which requires a diagnostic if duplicated in the same scope?

    Typedefs and enums are classified as definitions in the standard.

    --
    pete
    pete, Nov 3, 2005
    #12
  13. pete <> writes:
    > Gordon Burditt wrote:
    >>
    >> >Object definitions and function definitions
    >> >don't belong in header files, do they?

    >>
    >> typedefs do.
    >>
    >> >If declarations which are neither object defintions
    >> >nor function defintions, are declared twice, what's the harm?

    >>
    >> If you put the same typedef in twice, compilation fails.

    >
    > Can a "definition" be described as the kind of declaration
    > which requires a diagnostic if duplicated in the same scope?


    I don't know. I tried a while ago to construct a reasonable
    definition of "definition", but it was contradicted by the standard.

    > Typedefs and enums are classified as definitions in the standard.


    My thought at the time was that a "definition" is anything that
    introduces an identifier as a name for some newly created entity.
    (For a typedef, the entity in question is a type alias, not the type
    itself, since a typedef doesn't create a new type.) Thus an extern
    declaration isn't a definition because it merely refers to an entity
    defined elsewhere. I don't remember just what shot down my idea.

    I'm not convinced the standard uses the term consistently, so now I
    just avoid using it without qualification.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Nov 3, 2005
    #13
  14. QQ

    Netocrat Guest

    [OT] Re: A question about ifndef

    On Thu, 03 Nov 2005 18:34:35 +0000, pete wrote:

    > If it is a "definition" of that type,
    > then how can I consider you to be corrected?
    > Terminology is important to me,
    > even if you're better at it than I am.


    The poetry of that block of text in isolation deserves a repost.

    --
    http://members.dodo.com.au/~netocrat
    Netocrat, Nov 3, 2005
    #14
  15. QQ

    Flash Gordon Guest

    pete wrote:
    > Flash Gordon wrote:
    >
    >>pete wrote:
    >>
    >>>Ben Pfaff wrote:

    >>
    >><snip header guards>
    >>
    >>>>It's not just for compilation performance. (If it were, then I'd
    >>>>probably omit them in my header files, because they're ugly.)
    >>>>It's also to avoid compilation errors due to redefinitions:
    >>>>structures, unions, and enumerations (and some other kinds of
    >>>>entities?) may not be defined more than once.
    >>>
    >>>Object definitions and function definitions
    >>>don't belong in header files, do they?

    >>
    >>Yes, but I'm sure that is not what Ben was referring to.
    >>
    >>
    >>>If declarations which are neither object defintions
    >>>nor function defintions, are declared twice, what's the harm?

    >>
    >>The harm is that, for example,
    >>struct fred {int i;};
    >>struct fred {int i;};
    >>will not compile. Note that this is defining a struct, but *not*
    >>defining an object of that struct type.

    >
    >
    > My compiler agrees with you,
    > but I can't find any words in the standard which call
    > struct fred {int i;};
    > a definition.
    >
    > Got a reference?


    In N1124 section 6.7.2.3 Tags it says:
    | 6.7.2.3 Tags
    | Constraints
    | 1 A specific type shall have its content defined at most once.

    Everywhere else that I can see it refers to declarations, so I accept
    that my terminology was wrong.

    > I would describe
    > struct fred {int i;};
    > as a declaration of a complete struct type.


    Having checked the standard I have to agree.

    > So far, I only know of 4 kinds of definitions in a translation unit:
    > 1 object
    > 2 function
    > 3 enum
    > 4 typedef
    >
    > Do I need to add more to the list?


    No, but this just means there are some times of declaration you can't
    repeat within the same scope, which is a bit messy in terms of
    terminology IMHO but that is the way it is.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Nov 3, 2005
    #15
  16. QQ

    pete Guest

    Keith Thompson wrote:
    >
    > pete <> writes:


    > > Can a "definition" be described as the kind of declaration
    > > which requires a diagnostic if duplicated in the same scope?

    >
    > I don't know. I tried a while ago to construct a reasonable
    > definition of "definition", but it was contradicted by the standard.
    >
    > > Typedefs and enums are classified as definitions in the standard.

    >
    > My thought at the time was that a "definition" is anything that
    > introduces an identifier as a name for some newly created entity.
    > (For a typedef, the entity in question is a type alias, not the type
    > itself, since a typedef doesn't create a new type.) Thus an extern
    > declaration isn't a definition because it merely refers to an entity
    > defined elsewhere. I don't remember just what shot down my idea.


    I recall saying that a typedef dosen't do any more defining
    than a complete structure declaration.
    Now I'm thinking that maybe a struct declaration does as much
    defining as a typedef.

    > I'm not convinced the standard uses the term consistently, so now I
    > just avoid using it without qualification.


    It would be good, I think, if there was something that all
    definitions had in common with each other,
    that was unique to definitions.

    --
    pete
    pete, Nov 3, 2005
    #16
  17. QQ

    pete Guest

    Flash Gordon wrote:
    >
    > pete wrote:


    > > So far, I only know of 4 kinds of definitions in a translation unit:
    > > 1 object
    > > 2 function
    > > 3 enum
    > > 4 typedef
    > >
    > > Do I need to add more to the list?

    >
    > No, but this just means there are some times of declaration you can't
    > repeat within the same scope, which is a bit messy in terms of
    > terminology IMHO but that is the way it is.


    OK
    It's just the above 4 kinds of definitions,
    plus complete struct and union declarations.
    That's all nonrepeatable declarations that
    there can be in a translation unit,
    that can't be repeated within the same scope, right?

    --
    pete
    pete, Nov 4, 2005
    #17
  18. QQ

    pete Guest

    pete wrote:
    >
    > Flash Gordon wrote:
    > >
    > > pete wrote:

    >
    > > > So far, I only know of 4 kinds of definitions in a translation unit:
    > > > 1 object
    > > > 2 function
    > > > 3 enum
    > > > 4 typedef
    > > >
    > > > Do I need to add more to the list?

    > >
    > > No, but this just means there are some times
    > > of declaration you can't
    > > repeat within the same scope, which is a bit messy in terms of
    > > terminology IMHO but that is the way it is.

    >
    > OK
    > It's just the above 4 kinds of definitions,
    > plus complete struct and union declarations.
    > That's all


    of the

    > nonrepeatable declarations that
    > there can be in a translation unit,
    > that can't be repeated within the same scope, right?


    --
    pete
    pete, Nov 4, 2005
    #18
  19. QQ

    Jack Klein Guest

    On Fri, 04 Nov 2005 00:11:26 GMT, pete <> wrote
    in comp.lang.c:

    > pete wrote:
    > >
    > > Flash Gordon wrote:
    > > >
    > > > pete wrote:

    > >
    > > > > So far, I only know of 4 kinds of definitions in a translation unit:
    > > > > 1 object
    > > > > 2 function
    > > > > 3 enum
    > > > > 4 typedef
    > > > >
    > > > > Do I need to add more to the list?
    > > >
    > > > No, but this just means there are some times
    > > > of declaration you can't
    > > > repeat within the same scope, which is a bit messy in terms of
    > > > terminology IMHO but that is the way it is.

    > >
    > > OK
    > > It's just the above 4 kinds of definitions,
    > > plus complete struct and union declarations.
    > > That's all

    >
    > of the
    >
    > > nonrepeatable declarations that
    > > there can be in a translation unit,
    > > that can't be repeated within the same scope, right?


    Macros can't be redefined, unless undefine'd first. Macros
    effectively have file scope, their only exemption from the scoping
    rules that apply to other identifiers is that they can't be hidden by
    a redefinition in an inner scope.

    Some compilers allow redefinition of macros with identical replacement
    text as an extension, but this is non-conforming.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Nov 4, 2005
    #19
  20. QQ

    Tim Rentsch Guest

    Jack Klein <> writes:

    > Macros can't be redefined, unless undefine'd first. Macros
    > effectively have file scope, their only exemption from the scoping
    > rules that apply to other identifiers is that they can't be hidden by
    > a redefinition in an inner scope.
    >
    > Some compilers allow redefinition of macros with identical replacement
    > text as an extension, but this is non-conforming.


    Really? It seems like it's specifically allowed:

    6.10.3

    2 An identifier currently defined as an object-like macro shall
    not be redefined by another #define preprocessing directive
    unless the second definition is an object-like macro definition
    and the two replacement lists are identical. Likewise, an
    identifier as a function-like macro shall not be redefined by
    another #define preprocessing directive unless the second
    definition is a function-like macro definition that has the
    same number and spelling of parameters, and the two replacement
    lists are identical.


    6.10.3 p1 gives a definition for replacement lists being identical.
    Tim Rentsch, Nov 4, 2005
    #20
    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. Evan
    Replies:
    4
    Views:
    899
    Scott Condit
    Jul 12, 2003
  2. prettysmurfed
    Replies:
    3
    Views:
    10,303
    MPBroida
    Oct 24, 2003
  3. DrUg13

    ifndef define question

    DrUg13, Feb 7, 2004, in forum: C++
    Replies:
    5
    Views:
    16,816
    EventHelix.com
    Feb 8, 2004
  4. Peng Yu
    Replies:
    6
    Views:
    6,433
    Method Man
    Oct 4, 2004
  5. Chris Torek

    Re: defined(name) vs #ifdef AND #ifndef

    Chris Torek, Jul 2, 2003, in forum: C Programming
    Replies:
    0
    Views:
    806
    Chris Torek
    Jul 2, 2003
Loading...

Share This Page