Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > newbie question about preprocessing

Reply
Thread Tools

newbie question about preprocessing

 
 
sieg1974
Guest
Posts: n/a
 
      09-25-2003
Hi,

I have made a program that is divided in many group of functions, and
each of these groups has its .h and .c files ( for example dutils.h
and dutils.c ). And to avoid the same .h file to be include more than
once, I wrote these command everywhere where I need to include
something.

#ifndef H_DUTILS
# define H_DUTILS
# include "dutils.h"
#endif

Is it a good way to do it, or there is a better way?

Thanks,

Andre
 
Reply With Quote
 
 
 
 
Tom Zych
Guest
Posts: n/a
 
      09-25-2003
sieg1974 wrote:

> I have made a program that is divided in many group of functions, and
> each of these groups has its .h and .c files ( for example dutils.h
> and dutils.c ). And to avoid the same .h file to be include more than
> once, I wrote these command everywhere where I need to include
> something.


> #ifndef H_DUTILS
> # define H_DUTILS
> # include "dutils.h"
> #endif


> Is it a good way to do it, or there is a better way?


A better way is to put the same kind of logic inside the header file
itself:

#ifndef DUTILS_H /* note changed macro name */
#define DUTILS_H
[the rest of the header file here]
#endif

Then you only need #include "dutils.h" in the other files.

--
Tom Zych
This is a fake email address to thwart spammers.
Real address: echo '(E-Mail Removed)' | rot13
 
Reply With Quote
 
 
 
 
Robert Stankowic
Guest
Posts: n/a
 
      09-25-2003

"Tom Zych" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> sieg1974 wrote:
>
> > I have made a program that is divided in many group of functions, and
> > each of these groups has its .h and .c files ( for example dutils.h
> > and dutils.c ). And to avoid the same .h file to be include more than
> > once, I wrote these command everywhere where I need to include
> > something.

>
> > #ifndef H_DUTILS
> > # define H_DUTILS
> > # include "dutils.h"
> > #endif

>
> > Is it a good way to do it, or there is a better way?

>
> A better way is to put the same kind of logic inside the header file
> itself:
>
> #ifndef DUTILS_H /* note changed macro name */


Why did you change it?
AFAIK macro-names starting with upper case 'E' are reserved, so prefixing
the macro-name with H_ puts you on the safe side.

> #define DUTILS_H
> [the rest of the header file here]
> #endif
>
> Then you only need #include "dutils.h" in the other files.


Robert


 
Reply With Quote
 
Darrell Grainger
Guest
Posts: n/a
 
      09-25-2003
On Wed, 24 Sep 2003, sieg1974 wrote:

> Hi,
>
> I have made a program that is divided in many group of functions, and
> each of these groups has its .h and .c files ( for example dutils.h
> and dutils.c ). And to avoid the same .h file to be include more than
> once, I wrote these command everywhere where I need to include
> something.
>
> #ifndef H_DUTILS
> # define H_DUTILS
> # include "dutils.h"
> #endif
>
> Is it a good way to do it, or there is a better way?


This will work in some instances. It depends a little on your compiler.
There is nothing in the C standard that indicates this has to work.

Here is a scenario where this fails. I have a make file. Rather than
having a single command to compile everything at once I want to compile
each source file to an object file and then link them all together. In
case your are curious why, if I have 10,000 source files I don't want to
recompile all of them if I make a change to just one file.

If I have two files that #include the same header file, the make command
will compile the frst file, the compiler will see that this is the first
time we have included the header and #include it. When I compile the
second file, this is a new run of the compiler so the compiler will thikn
we are accessing the header file for the first time, again. When we link
the object files from file one and file two there will be trouble.

Bottom line, this might work for you but it depends on how your compiler
works. Something to note: what would happen if it works for your current
compiler but two years from now you realize you need to change your setup
and it stops working? That is, you switch to a system I just described.

--
darrell at cs dot toronto dot edu
or
main(){int j=1234;char t[]=":@abcdefghijklmnopqrstuvwxyz.\n",*i=
"iqgbgxmdbjlgdv.lksrqek.n";char *strchr(const char *,int);while(
*i){j+=strchr(t,*i++)-t;j%=sizeof t-1;putchar(t[j]);} return 0;}
 
Reply With Quote
 
sieg1974
Guest
Posts: n/a
 
      09-25-2003
Tom Zych <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> sieg1974 wrote:
>
> > I have made a program that is divided in many group of functions, and
> > each of these groups has its .h and .c files ( for example dutils.h
> > and dutils.c ). And to avoid the same .h file to be include more than
> > once, I wrote these command everywhere where I need to include
> > something.

>
> > #ifndef H_DUTILS
> > # define H_DUTILS
> > # include "dutils.h"
> > #endif

>
> > Is it a good way to do it, or there is a better way?

>
> A better way is to put the same kind of logic inside the header file
> itself:
>
> #ifndef DUTILS_H /* note changed macro name */
> #define DUTILS_H
> [the rest of the header file here]
> #endif
>
> Then you only need #include "dutils.h" in the other files.


But what would happen if I had two or more .c files that would include
stdio.h for example? Does stdio.h have these ifndef, define, endif
inside it? Or will it just be included more than once?

Andre
 
Reply With Quote
 
Mike Wahler
Guest
Posts: n/a
 
      09-25-2003

"sieg1974" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Tom Zych <(E-Mail Removed)> wrote in message

news:<(E-Mail Removed)>...
> > sieg1974 wrote:
> >
> > > I have made a program that is divided in many group of functions, and
> > > each of these groups has its .h and .c files ( for example dutils.h
> > > and dutils.c ). And to avoid the same .h file to be include more than
> > > once, I wrote these command everywhere where I need to include
> > > something.

> >
> > > #ifndef H_DUTILS
> > > # define H_DUTILS
> > > # include "dutils.h"
> > > #endif

> >
> > > Is it a good way to do it, or there is a better way?

> >
> > A better way is to put the same kind of logic inside the header file
> > itself:
> >
> > #ifndef DUTILS_H /* note changed macro name */
> > #define DUTILS_H
> > [the rest of the header file here]
> > #endif
> >
> > Then you only need #include "dutils.h" in the other files.

>
> But what would happen if I had two or more .c files that would include
> stdio.h for example?


Then the text from the stdio header will be pasted into
each .c file. Note that this will create two separate
translation units. The header is not being #included
more than once.

What I think you might have meant to ask is what
happens if #include <stdio.h> appears more than
once in the same source file.

Answer:
If the implementation is compliant The Right Thing(tm)
will happen.

>Does stdio.h have these ifndef, define, endif
> inside it?


It might.

> Or will it just be included more than once?


The standard only stipulates that #including
a standard header more than once has the
same effect as if #included only once (with
one exception, see below). How this is achieved
is up to the implementation, but using 'include
guards' is common.

C&V:
================================================== ===========
ISO/IEC 9899:1999 (E)

[...]

7.1.2 Standard headers

[...]

4 Standard headers may be included in any order; each may be
included more than once in a given scope, with no effect
different from being included only once, except that the
effect of including <assert.h> depends on the definition
of NDEBUG (see 7.2). If used, a header shall be included
outside of any external declaration or definition, and it
shall first be included before the first reference to any
of the functions or objects it declares, or to any of the
types or macros it defines. However, if an identifier is
declared or defined in more than one header, the second and
subsequent associated headers may be included after the
initial reference to the identifier. The program shall not
have any macros with names lexically identical to keywords
currently defined prior to the inclusion.
================================================== ===========

-Mike


 
Reply With Quote
 
Arthur J. O'Dwyer
Guest
Posts: n/a
 
      09-25-2003

On Thu, 25 Sep 2003, Darrell Grainger wrote:
>
> On Wed, 24 Sep 2003, sieg1974 wrote:
> >
> > I have made a program that is divided in many group of functions, and
> > each of these groups has its .h and .c files ( for example dutils.h
> > and dutils.c ). And to avoid the same .h file to be include more than
> > once, I wrote these command everywhere where I need to include
> > something.
> >
> > #ifndef H_DUTILS
> > # define H_DUTILS
> > # include "dutils.h"
> > #endif
> >
> > Is it a good way to do it, or there is a better way?

>
> This will work in some instances. It depends a little on your compiler.
> There is nothing in the C standard that indicates this has to work.


While technically true, that is a vacuous statement. The *only*
implementation-dependent part of the above is the bit between the
quotes -- some file systems might not know what "dutils.h" is meant
to represent. In the context of c.l.c and hosted implementations,
I think we can assume the OP's compiler has a decent file system.

The above code does the following:

Check whether H_DUTILS is defined. This check will be false
initially, since the implementation is not allowed to define
H_DUTILS for itself.
If not, define H_DUTILS,
and then #include a certain header file.
Otherwise, do nothing.

This is perfectly well-defined (except for the bit in quotes, as
I mentioned), and will work on every C compiler in existence (as
well as every C compiler *not* in existence).

[Tangential: Someone else suggested #defining DUTILS_H instead.
That's harmless in this case, but stupid in general. Don't listen
to that person.]


> Here is a scenario where this fails. I have a make file. Rather than
> having a single command to compile everything at once I want to compile
> each source file to an object file and then link them all together. In
> case your are curious why, if I have 10,000 source files I don't want to
> recompile all of them if I make a change to just one file.


Okay; so far that's all irrelevant. 'make' is off-topic here,
and the compiler doesn't care how it's invoked anyway. Make or
no make, it's all the same to it.

> If I have two files that #include the same header file, the make command
> will compile the frst file, the compiler will see that this is the first
> time we have included the header and #include it. When I compile the
> second file, this is a new run of the compiler so the compiler will thikn
> we are accessing the header file for the first time, again.


Yes, of course. That's the way most operating systems work -- program
data is "forgotten" between runs of the same program.

> When we link
> the object files from file one and file two there will be trouble.


Why? What kind of trouble are you experiencing?


-Arthur,
sounds like a case of "Doctor, it hurts when I do this..."

 
Reply With Quote
 
Tom Zych
Guest
Posts: n/a
 
      09-26-2003
"Arthur J. O'Dwyer" wrote:

> [Tangential: Someone else suggested #defining DUTILS_H instead.
> That's harmless in this case, but stupid in general. Don't listen
> to that person.]


Um, why?

--
Tom Zych
This is a fake email address to thwart spammers.
Real address: echo '(E-Mail Removed)' | rot13
 
Reply With Quote
 
Tom Zych
Guest
Posts: n/a
 
      09-26-2003
Robert Stankowic wrote:

> "Tom Zych" <(E-Mail Removed)> schrieb im Newsbeitrag
> news:(E-Mail Removed)...


> > #ifndef DUTILS_H /* note changed macro name */


> Why did you change it?
> AFAIK macro-names starting with upper case 'E' are reserved, so prefixing
> the macro-name with H_ puts you on the safe side.


I was going to say, that's how the standard headers on my system do
it, but checking, I see they actually do _STDIO_H and such. I want
to see why Arthur says it's stupid.

--
Tom Zych
This is a fake email address to thwart spammers.
Real address: echo '(E-Mail Removed)' | rot13
 
Reply With Quote
 
Kevin Easton
Guest
Posts: n/a
 
      09-26-2003
Tom Zych <(E-Mail Removed)> wrote:
> Robert Stankowic wrote:
>
>> "Tom Zych" <(E-Mail Removed)> schrieb im Newsbeitrag
>> news:(E-Mail Removed)...

>
>> > #ifndef DUTILS_H /* note changed macro name */

>
>> Why did you change it?
>> AFAIK macro-names starting with upper case 'E' are reserved, so prefixing
>> the macro-name with H_ puts you on the safe side.

>
> I was going to say, that's how the standard headers on my system do
> it, but checking, I see they actually do _STDIO_H and such. I want
> to see why Arthur says it's stupid.


It's irrelevant anyway (you can't use names like _DUTILS_H yourself
either) - the implementation headers are allowed to do things that your
code isn't. The reason for this is to give the implmentation (compiler
and libraries) a namespace in which it can define identifiers or
keywords with whatever semantics it wants to / needs to.

- Kevin.

 
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
Re: Summary: translation units, preprocessing, compiling and linking? Victor Bazarov C++ 0 05-09-2006 11:00 PM
Re: Summary: translation units, preprocessing, compiling and linking? Mark A. Gibbs C++ 0 05-09-2006 11:00 PM
Summary: translation units, preprocessing, compiling and linking? Steven T. Hatton C++ 7 06-03-2004 06:01 PM
Preprocessing directives Ron C++ 3 11-12-2003 04:45 AM
Indentation of preprocessing directives Dave C++ 2 11-03-2003 03:34 AM



Advertisments