Game Development Community

C++ Question

by Carl A Harris · in Torque Game Engine · 08/13/2008 (10:34 pm) · 9 replies

I should know the answer to this question, but I seem to be brain dead at the moment and can't remember how/why this works.

With preprocessor directives such as:

#ifndef _EXAMPLEOBJ_H_
#define _EXAMPLEOBJ_H_

and:

#ifndef _PLAYER_H_
#include "game/player.h"
#endif

I understand that they are both checking for a definition. Such as :

If not defined _EXAMPLEOBJ_H_
then define _EXAMPLEOBJ_H_

or

If not defined _PLAYER_H_
then goto the "game" folder, include the "player.h" file
(which will have a #define _PLAYER_H_ in it somewhere)
then mark the end of the if

What I'm trying to remember, is what exactly does the definition do for the program?
I know it's a directive, but for the life of me I can't remember why I need to have them.

Are these just check points to insure that I have included all the code?

#1
08/13/2008 (10:40 pm)
Make header files identical by defining a token once the file has been included and checking that the token was not set at the top of that file.
#2
08/13/2008 (11:42 pm)
> Are these just check points to insure that I have included all the code?

actually they're checkpoints to ensure that you don't include the same .h file twice.

consider the following (hypothetical) situation:

player.h includes say gameBase.h,
and then AIPlayer.h includes gameBase.h and player.h,

then when AIPlayer.h is included, gameBase.h will be included twice,
resulting in duplicate definitions etc, which are compile errors.

so this is a way around that,
by making the .h files automatically "hide" their bodies if they've already been included once.

in your first example don't forget to include the body of the file itself. eg:
foo.h
#ifndef FOO_H
#define FOO_H
// this is the body of the .h file,
// blah blah blah declaring classes function globals, whatever
#endif

so you can see that if you include foo.h several times,
its body only gets included the first time.

re the second example:
#ifndef _PLAYER_H_
#include "game/player.h"
#endif

for my money that's a bad construct,
because it requires the file doing the including to be an expert of sorts on what player.h is #defining.
the first method is sufficient.


.. at least, that's my take on all this.
#3
08/13/2008 (11:59 pm)
That's what I thought I remembered them doing, but I wanted to make sure. So I don't making start retarded mistakes. :)

Thanks Guys.
#4
08/14/2008 (8:32 am)
Quote:
re the second example:
#ifndef _PLAYER_H_
#include "game/player.h"
#endif

is a historical artifact from the days when disk access (random seek, open file, read...) was so slow that including this check in the including file would result in dramatic build time increases because you could avoid the disk I/O.

I agree with Orion... don't do that in new code.

The first way is better, and you can even improve it a bit more by using the widely-supported-but-not-standard '#pragma once' right before the top of the include guard, in the .h files.

'#pragma once' acheives the speed benefits of the second example without the drawback Orion points out.
#5
08/14/2008 (10:21 am)
Yikes!

i remember using the Aztec C compiler on the Amiga, with only two floppy drives and 2MB of ram,
so, yeah, i can see how that second example would be a good thing.
#6
08/14/2008 (11:56 am)
@Tim - Thanks for the historical info. That actually helped more than you know. It explains why I always thought the directives were a bit archaic, but couldn't figure out why.

I've been writing C on and off since my "MS Quick C 2.5" days in the early 90's.

Having said that, can you believe I have never even once used a #pragma statement? Though I was teaching myself C from a book. I don't remember that the books I was using covered it. Then again, I can't see it wouldn't have. Being self taught, though cheap, apparently has it's drawbacks. :)
#7
08/14/2008 (12:06 pm)
#pragma's are largely platform and compiler dependent, so it would make sense that many C language books (covering coding in C and the specification of the language, and not a particular compiler implementation) would not cover them.
#8
08/14/2008 (12:24 pm)
Any chance that you could explain it or tell me where I could find a book that explains it's use?
#9
08/14/2008 (1:03 pm)
The documentation for your specific compiler will have all the various #pragma's that are supported documented.

For Visual Studio:
http://msdn.microsoft.com/en-us/library/d9x1s805(vs.71).aspx

For GNU:
http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html