Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > A question about ifndef

Reply
Thread Tools

A question about ifndef

 
 
QQ
Guest
Posts: n/a
 
      11-02-2005
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!

 
Reply With Quote
 
 
 
 
Default User
Guest
Posts: n/a
 
      11-02-2005
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

 
Reply With Quote
 
 
 
 
Walter Roberson
Guest
Posts: n/a
 
      11-02-2005
In article < .com>,
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
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      11-02-2005
(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.
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      11-02-2005
"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
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      11-03-2005
Ben Pfaff wrote:
>
> (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
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      11-03-2005
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.
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      11-03-2005
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
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      11-03-2005
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
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      11-03-2005
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to use #ifndef #define, etc, in a macro definition Peng Yu C++ 6 10-03-2004 11:50 PM
ifndef define question DrUg13 C++ 5 02-08-2004 02:27 AM
#ifndef #define #endif and multiple definitions problem prettysmurfed C++ 3 10-24-2003 08:30 PM
#if !defined() vs #ifndef Evan C++ 4 07-12-2003 10:28 AM
Re: defined(name) vs #ifdef AND #ifndef Chris Torek C Programming 0 07-02-2003 01:28 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57