Hi, What is the meaning of #ifndef

Q

Qiao Jian

I am new to c. Today I just read an h file within which there is statements:

#ifndef _RANDOM_H
#define _RANDOM_H

So what is the meaning or purpose of this statement?
When should I use such statement in my own program?
Thank you so much!
 
P

pete

Qiao said:
I am new to c. Today I just read an h file within which there is statements:

#ifndef _RANDOM_H
#define _RANDOM_H

So what is the meaning or purpose of this statement?

If the h file is included more than once,
either directly or indirectly through other h files,
then the compiler only sees the contents of the h file once.
That's important when the h file contains the kind of declarations
that are not allowed to be duplicated in a c file.
When should I use such statement in my own program?

In every h file. There's no bad consequences
if it is used in an h file when it isn't needed.

Macro names begining with
a leading underscore followed by an uppercase letter
or a second underscore,
are reserved for use by the implemantation.
So are macros begining with a upper case E.

A good convention for the C programmer is:

/* BEGIN random.h */

#ifndef H_RANDOM
#define H_RANDOM

/*
** Contents of h file goes here.
*/

#endif

/* END random.h */
 
A

Alex Fraser

Qiao Jian said:
I am new to c. Today I just read an h file within which there is statements:

#ifndef _RANDOM_H
#define _RANDOM_H

So what is the meaning or purpose of this statement?

"#ifndef identifier" means "if 'identifier' is not defined as a macro".
When should I use such statement in my own program?

It's generally a good idea whenever you create header files; the idiom above
is part of what is usually called an "include guard". See
http://www.eskimo.com/~scs/C-faq/q10.7.html

Another time when #ifndef and #ifdef are useful is when you develop code
that is to be compiled on multiple platforms. Slight differences between the
platforms can be allowed for by conditionally including code relevant to the
platform for which the source is being compiled (and excluding code for
others).

Alex
 
J

Joe Wright

Qiao said:
I am new to c. Today I just read an h file within which there is statements:

#ifndef _RANDOM_H
#define _RANDOM_H

So what is the meaning or purpose of this statement?
When should I use such statement in my own program?
Thank you so much!

It's generally called an 'include guard' so that the declarations of a
particular header will only be included once in a particular translation
unit.

One of the 'features' of C is that not only can .c files #include
headers but header files themselves can #include headers too. In order
to avoid the same header's declarations evaluating two or more times we
use the 'guard' like this..

foo.h
.....
#ifndef FOO_H
#define FOO_H
#define FOOS 42
#endif
.....

bar.h
.....
#ifndef BAR_H
#define BAR_H
#include "foo.h"
#define BARS 24
#endif
.....

Now, if in pro.c I include bar.h, both bar.h and foo.h are included and
both BAR_H and FOO_H are defined. If later in pro.c I include foo.h we
find FOO_H already defined and so the contents of foo.h (between #ifndef
and #endif) are ignored.

Include guards are optional. I always use them. Habit.
 
A

Alberto =?iso-8859-1?Q?Gim=E9nez?=

El 16 Apr 2005 04:09:13 -0700, Qiao Jian escribió:
#ifndef _RANDOM_H
#define _RANDOM_H

So what is the meaning or purpose of this statement?

It's a "guard". It is used in header files that declare external
functions. These two statements are used to avoid multiple inclusion of
the same header.

The first time you #include that code, _RANDOM_H is not defined, so will
define it and include the code between the #define and the #endif (sould
be at the end of the header code).

Next #includes won't include that code, because _RANDOM_H is yet defined
and the #ifndef condition isn't true.
When should I use such statement in my own program?

I usually use such statements in header files which are
meant to be an "interface" for a module/library/etc. For example:

/* list.h */
#ifndef LIST_H
#define LIST_H

struct list {
....
};

struct list *list_create(parameters);

/* more declarations */

#endif /* LIST_H */

/* list.c */
#include "list.h"

/* list ADT implementation */


But you must remember that names beginning with '_' character are
reserved for the implementation (it is right? please correct me).
 
B

Ben Pfaff

Today I just read an h file within which there is statements:

#ifndef _RANDOM_H
#define _RANDOM_H

So what is the meaning or purpose of this statement?

I see that others have given you guidance on the purpose of these
line, but so far no one has pointed out that they are not, in
fact, statements. These are preprocessor directives for
conditional compilation.
 
Q

Qiao Jian

Ben Pfaff said:
I see that others have given you guidance on the purpose of these
line, but so far no one has pointed out that they are not, in
fact, statements. These are preprocessor directives for
I see, it just provide some info to compiler ,and will not be compiled
Thanks all the kind guys above. I think I have an idea of the meaning
of such directives with .h file
 
E

Emmanuel Delahaye

Qiao Jian wrote on 17/04/05 :
Thanks all the kind guys above. I think I have an idea of the meaning
of such directives with .h file

Just keep in mind that identifiers starting with '_' followed by an
uppercase belong to the implementatation namespace. While technically
possible, using them in the user namespace invokes un undefined
behaviour.

If a header from your implementation of C has '_RANDOM_H', it's just
fine. But if it is one of your own, I suggest 'RANDOM_H' or better
'H_RANDOM' to prevent from another namespace invasion (Identifiers
beginning with 'E' belong to the implementation...).

I personally use the folowing pattern:

H_<initials/company>_<file name>_<date><time>

date in YYYYMMDD format and time in HHMMSS format

It provides a better protection against doublons.

For example :

H_ED_RANDOM_20080416123300

that is used :

#ifndef H_ED_RANDOM_20080416123300
#define H_ED_RANDOM_20080416123300

/* ... */


#endif /* guard */

Of course, this is automated. (UltraEdit can do that, and I have
written a separated utility too.)

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"
 
C

Chris Croughton

I personally use the folowing pattern:

H_<initials/company>_<file name>_<date><time>

date in YYYYMMDD format and time in HHMMSS format

It provides a better protection against doublons.

For example :

H_ED_RANDOM_20080416123300

that is used :

#ifndef H_ED_RANDOM_20080416123300
#define H_ED_RANDOM_20080416123300

/* ... */

#endif /* guard */

Of course, this is automated. (UltraEdit can do that, and I have
written a separated utility too.)

Is that utility publically available in source form? I could of course
write my own, but if there's an existing one it may be more efficient to
reuse it...

(I use a Vim macro and template files in general, but I have old files
which could do with being guarded properly...)

Chris C
 
E

Emmanuel Delahaye

Chris Croughton wrote on 17/04/05 :
Is that utility publically available in source form? I could of course
write my own, but if there's an existing one it may be more efficient to
reuse it...

(I use a Vim macro and template files in general, but I have old files
which could do with being guarded properly...)

Chris C

The project files

c.c \clib\c\src
c_guard.c \clib\c\src
c_tools.c \clib\c\src
ascii.c \clib\ed\src
str.c \clib\ed\src
sys.c \clib\ed\src
fic.c \clib\ed\src
main.c

The main file is here
http://mapage.noos.fr/emdel/clib/tools/guard/src/main.c

The 'C' files are here

http://mapage.noos.fr/emdel/clib/c/inc/c.h
http://mapage.noos.fr/emdel/clib/c/inc/ci.h
http://mapage.noos.fr/emdel/clib/c/src/c.c
http://mapage.noos.fr/emdel/clib/c/src/c_tools.c
http://mapage.noos.fr/emdel/clib/c/src/c_guard.c


the missing files (ED) are accessible by

http://mapage.noos.fr/emdel/clib.htm

The 'initial/company' field is ED by default and can be redefined by
the GUARD environment variable.

Usage:

-> Returned when the program is invoked without parameter:

USAGE guard <header file .h or .hpp>

-> Returned when the file is unknown:

USAGE guard <header file .h or .hpp>
test.h: No such file or directory

-> Returned when the file is known:

Nothing !

The test file was:

<begin>
/* test.h */
<end>

It has been modified to

<begin>
#ifndef H_ED_TEST_20050417191614
#define H_ED_TEST_20050417191614

#ifdef __cplusplus
extern "C"
{
#endif

/* test.h */


#ifdef __cplusplus
}
#endif

#endif /* guard */

/* Guards added by GUARD (c) ED 2000-2005 Apr 17 2005 Ver. 1.7 */
<end>

The original file has been renamed in test.gua

Let me know if you are in trouble.

The use and enhancement of this utility and of the clib files is free
(in both means) as long as the copyright indications "(c) ED
<year>[-<year>]" are mentioned. In case of enhancement, you can add you
own (c).

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top