Three #include guards, which will never break?

  • Thread starter lovecreatesbeauty
  • Start date
L

lovecreatesbeauty

Sometimes programmers will define macros at command line like:

$ gcc -DF1_H ...
$ gcc -DF1_H=0 ...
$ gcc -DF1_H=1 ...

One of following three lines labeled as #1, #2, #3 may provide #include
guard and avoid errors may be introduced by redundant #include. Is
there any flaw with each of them? Which one will never break?

#if F1_H /*#1*/
/*#if !defined(F1_H)*/ /*#2*/
/*#ifndef F1_H */ /*#3*/
#define F1_H

/*more stuff here ...*/

#endif
 
A

Andrew Poelstra

Sometimes programmers will define macros at command line like:

$ gcc -DF1_H ...
$ gcc -DF1_H=0 ...
$ gcc -DF1_H=1 ...

One of following three lines labeled as #1, #2, #3 may provide #include
guard and avoid errors may be introduced by redundant #include. Is
there any flaw with each of them? Which one will never break?

#if F1_H /*#1*/
/*#if !defined(F1_H)*/ /*#2*/
/*#ifndef F1_H */ /*#3*/
#define F1_H

/*more stuff here ...*/

#endif

Most all code I've seen uses #ifndef. That will be the most easily
understood. I've never seen #2 in my life.
 
W

Walter Roberson

Most all code I've seen uses #ifndef. That will be the most easily
understood. I've never seen #2 in my life.

#1 is flawed because it tests values rather than definedness.

#2 and #3 are flawed because the # is not the first non-whitespace
on the line, so they are not going to be treated as preprocessor commands.

#ifndef and #if !defined() are exactly the same, but the latter is more
easily extendable without having to go back and change the directive.
#if !defined() definitely does get used.
 
C

Chris Dollin

Walter said:
#1 is flawed because it tests values rather than definedness.

#2 and #3 are flawed because the # is not the first non-whitespace
on the line, so they are not going to be treated as preprocessor commands.

#2 and #3 are commented-out /alternatives/ to #1.
 
A

Al Balmer

Most all code I've seen uses #ifndef. That will be the most easily
understood. I've never seen #2 in my life.

No? I prefer it, actually. It's more versatile and can be extended to
more complex tests if needed.
 
W

Walter Roberson

Walter Roberson wrote:
#2 and #3 are commented-out /alternatives/ to #1.

Re-examine the original posting:

The commenting around the directives are *part* of lines #2 and #3.
There is no indication that we are to remove the commenting in our
consideration. We are told, "One of the following three lines", not
"One of the following three lines, after having the leading comment
delimiters removed on the second and third line but not touching the
comment delimiters around the # labelling".
 
R

Roberto Waltman

lovecreatesbeauty said:
No? I prefer it, actually. It's more versatile and can be extended to
more complex tests if needed.

Such as the following. The rationale in this case was to stop
lint-like tools from complaining about undefined preprocessor symbols
when using the more common "#ifdef ..." form.

/* Use -DSTANDALONE_TEST=1 in the makefile to enable */
/* statistics collection and profiling timers. */

#if !defined(STANDALONE_TEST)
# define STANDALONE_TEST 0
#endif

#if defined(STANDALONE_TEST) && (STANDALONE_TEST==1)
/* insert test/debug code here */
...
#endif
 
R

Richard Tobin

Walter Roberson said:
The commenting around the directives are *part* of lines #2 and #3.
There is no indication that we are to remove the commenting in our
consideration.

The reader is expected to apply common sense.

-- Richard

 
B

Ben Pfaff

Roberto Waltman said:
Such as the following. The rationale in this case was to stop
lint-like tools from complaining about undefined preprocessor symbols
when using the more common "#ifdef ..." form.

#if !defined(STANDALONE_TEST)
# define STANDALONE_TEST 0
#endif

Given the above, you don't need the defined(...) test below,
because STANDALONE_TEST will always be defined.
 
W

Walter Roberson

The reader is expected to apply common sense.

Not in answering what is obviously a homework or test question:
such questions must be read literally because the literal reading
is what the marker is expecting.

It would have been easy enough for the test-poser to use three
different sections if the commenting out had not been intended -as-
commenting out.
 
R

Roberto Waltman

Ben Pfaff said:
Given the above, you don't need the defined(...) test below,
because STANDALONE_TEST will always be defined.

You are right, of course. I pasted a few lines from two different
files and saw that after posting. I seems I am having another low
coffee pressure incident...
 
C

Chris Dollin

Walter said:
Re-examine the original posting:


The commenting around the directives are *part* of lines #2 and #3.

Yes, I see that. That's what makes those lines "commented out". Were
the lines uncommented, the example text would be illegal, or at
least incomplete.
There is no indication that we are to remove the commenting in our
consideration.

There's no indication that we should assume the question is
sensible, either, but that hasn't stopped you treating it as
such.
We are told, "One of the following three lines", not
"One of the following three lines, after having the leading comment
delimiters removed on the second and third line but not touching the
comment delimiters around the # labelling".

That's why we prefer informal to formal languages when communicating
with people about the non-critical parts of a problem.

Ain't English great?
 
L

lovecreatesbeauty

Chris said:
That's why we prefer informal to formal languages when communicating
with people about the non-critical parts of a problem.

Thanks. I'm not a native English speaker and always feel uneasy to
express myself in English. It's not my homework, I have no homework for
a long time after I graduated.

Years ago, I read a C coding guideline and it mentioned the usage of
#if expr or #if !defined(expr) for #include guard instead of #ifndef
expr. I can not find that document again, I'm not clear why it insisted
on using #if or #if !defined() but not #ifndef.
 
P

pete

lovecreatesbeauty wrote:
Years ago, I read a C coding guideline and it mentioned the usage of
#if expr or #if !defined(expr) for #include guard instead of #ifndef
expr. I can not find that document again,
I'm not clear why it insisted
on using #if or #if !defined() but not #ifndef.

I prefer #ifndef because the next line is #define
and I like the way that those two lines line up.

/* BEGIN file.h */

#ifndef H_FILE_H
#define H_FILE_H
/*
**
*/
#endif

/* END file.h */
 

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,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top