Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What does '#if 0' mean??

4,041 views
Skip to first unread message

Peter Smith

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
For instance,

#if 0
/* do something */
#else
/* do something else */
#endif

What is '0' and how is it 'defined'?!

Thanks.

User923005

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
P.S.:

>For instance,
>
>#if 0
> /* do something */
Never, never, never, never never, never, never, never, never, never, never
never, never, never, never, never, never, never never, never, never, never,
never, never, never never, never, never, never, never, never, never never,
never, never, never, never, never, never never, never, never, never, never
do this

>#else
> /* do something else */

Always do this.

>#endif

>What is '0' and how is it 'defined'?!

It is the successor to -1, and is defined using the piano axioms.

In C, zero is false. Non zero is true. It is a kind of clever way to comment
out a giant block of stuff.
--
C-FAQ ftp sites: ftp://ftp.eskimo.com ftp://rtfm.mit.edu
Hypertext C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-FAQ Book: ISBN 0-201-84519-9.
Want Software? Algorithms? Pubs? http://www.infoseek.com

Martin Ambuhl

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to

Peter Smith wrote in message <35D3C9F5...@mindspring.com>...

|For instance,
|
|#if 0
| /* do something */
|#else
| /* do something else */
|#endif
|
|What is '0' and how is it 'defined'?!
|


0 is zero.
How it is defined:
For any group G (which includes fields and integral domains). there
exists for any operation over the group (written here as op) a unique
element e in G having the property that for every a in G:

a op e == e op a == a.

That element e is called the identity element.
When the operation is addition, op is + and e is 0 (zero).

since
#if exp
/* stuff */
#endif

translates /* stuff */ only if exp evaluates to non-zero, and zero never
evaluates to non-zero, /* stuff */ is never translated if exp == 0.

Martin Ambuhl (mam...@tiac.net)
/* Newsgroup posts also e-mailed */

Richard Stamp

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
Peter Smith wrote in message <35D3C9F5...@mindspring.com>...
>For instance,
>
>#if 0
> /* do something */
>#else
> /* do something else */
>#endif
>
>What is '0' and how is it 'defined'?!

0 is just the number which comes before 1. It's important here because, in
C, 0 counts as "false".

Thus the section between '#if 0' and '#else' will never be compiled and the
section between '#else' and '#endif' will always be compiled.

If you found this weird arrangement in real code I'd guess the most likely
explanation is that the condition originally read something different but
was changed to always select the second branch. '#if 0' is useful, however,
to "comment out" chunks of code, like this:

#if 0
/* This doesn't seem to work, I'll figure it out later */
fflush(stdin);
#endif

You can't comment this out using /* ... */ because comments don't nest.
'#if 0' ... '#endif' is the best mechanism we have for temporarily excluding
bits of code in C.

Cheers,
Richard
--
Richard Stamp, Cambridge, UK


Daniel Brockhaus

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
On Fri, 14 Aug 1998 01:24:05 -0400, Peter Smith
<psmi...@mindspring.com> wrote:

>#if 0
> /* do something */
>#else
> /* do something else */
>#endif
>
>What is '0' and how is it 'defined'?!

"#if" works just like "if", only that it's a command to the preprocessor
to include/exclude a certain portion of code. "#if 0" means "exclude
always".

This construct is used to comment out a block of code that is not being
used right now. If, for example, you're changing a piece of code and
you're not certain of the consequences your change might have, you do:

#if 0
/* old code, the preprocessor will throw this away */
#else
/* your new code, the preprocessor will hand this to the compiler */
#endif

If the changes work fine, you eventually remove the "#if 0" part. If you
cannot get it right, you remove the "#else"-part.

HTH,

Daniel


Dik T. Winter

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
In article <199808140531...@ladder01.news.aol.com> user9...@aol.com (User923005) writes:
> It is the successor to -1, and is defined using the piano axioms.

No, no. The piano accioms define the successor of C (it is Cis or C#).
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

J. Benz

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to

Daniel Brockhaus wrote:

> On Fri, 14 Aug 1998 01:24:05 -0400, Peter Smith
> <psmi...@mindspring.com> wrote:
>
> >#if 0
> > /* do something */
> >#else
> > /* do something else */
> >#endif
> >
> >What is '0' and how is it 'defined'?!

Actually, I have seen a considerably useful application of this. This is
the only place I would support this construct in *real* code. It is simply
a programmer's tool for debugging code. It occurs in Unix processes where a
parent process forks a child process. If you've ever worked in such a
system, and have tried to debug the child module with the debugger, I'm sure
you've run up against the problem this can solve. Once the parent forks,
the child is off and running, and may actually complete before you can grab
the child with the debugger (many debuggers now can automatically grab the
child, but many still can't). So, just after the fork, or as the opening
salvo of an exec'd process, you can code:

#if 0
int lock = 1;

while ( lock ) {
sleep( 5 );
}
#endif

Now, the developer can simply change #if 0 to #if TRUE, or just delete the #
directives completely, recompile, and run the parent. The child will be
locked up in the loop, giving you time to grab it in the debugger. Then you
just stuff a zero into the lock variable, and you can step into the child's
code. The #if 0 construct just allows you to avoid having to recode the
loop every time you want to test the child module - and has no effect on
released code (unless some sleepyhead programmer forgets and leaves the
infinite loop in the code for the production release, but none of US would
ever do that...). Course, you probably want to put some more robust
activity in the loop, perhaps a printf or something, so it's not as trivial
as it appears, and it's mighty convenient when you're staring at a
late-night emergency bug.


Sunil Rao

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
User923005 <user9...@aol.com> wrote, and I reply...

>>What is '0' and how is it 'defined'?!
>It is the successor to -1, and is defined using the piano axioms.

erm... perhaps you meant Peano???

>In C, zero is false. Non zero is true. It is a kind of clever way to comment
>out a giant block of stuff.


--
"I see you have books under your arm, brother. It is indeed a rare pleasure
these days to come across somebody that still reads, brother."

- Anthony Burgess

Tom Watson

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
User923005 wrote:
>
> P.S.:
> >For instance,

> >
> >#if 0
> > /* do something */
> Never, never, never, never never, never, never, never, never, never, never
> never, never, never, never, never, never, never never, never, never, never,
> never, never, never never, never, never, never, never, never, never never,
> never, never, never, never, never, never never, never, never, never, never
> do this
>
> >#else
> > /* do something else */
> Always do this.
>
> >#endif

>
> >What is '0' and how is it 'defined'?!
> It is the successor to -1, and is defined using the piano axioms.
>
> In C, zero is false. Non zero is true. It is a kind of clever way to comment
> out a giant block of stuff.

This a common way to "turn off" code. It works MUCH BETTER that
attempting to
add a '/*' at the beginning, and '*/' at the end. There are a couple of
reasons for this:
1) Comments in C DON'T nest. They never have, and they never will.
Any compiler that has an option is seriously Dain Bramaged!! Users
Who think that comments nest have similar problems.
2) '#if 0' Actually does nest, as long as you pair it with the
corresponding
'#else' and '#endif' pre-processor lines.

Notes:
The pre-processor belives that it has C-like statements between its
'#if/#ifdef' and
'#else/#endif' directives. Not having them (like you quote a chapter of
_War and Peace_) can lead to problems. If you have general coments, the
better place to have them is between real comment delimiters (i.e. '/*'
and '*/').
Some compilers issue a warning if you have a '/*' (begin comment
delimiter) inside a comment. The warning is fine, as it MAY indicate an
error. Sometimes it IS useful, especially if your compiler doesn't like
C9X '//' comments.
Sometimes having a chunk of 'turned off' code is a documentation item to
aid the understanding of the code that took its place.

Remember, the code you comment today may be the code you don't
understand in 6 months without the comments. You may be your own worst
enemy!!
--
Tom Watson I'm at work now (Generic short signature)
twa...@metricom.com (Home:t...@johana.com)

User923005

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
Sunil:

>User923005 <user9...@aol.com> wrote, and I reply...
>>>What is '0' and how is it 'defined'?!
>>It is the successor to -1, and is defined using the piano axioms.
>
>erm... perhaps you meant Peano???
Well, as Dik Winter said, since I did not see sharp, now I'll have to be flat.

Larry Weiss

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
Martin Ambuhl wrote:
> #if exp
> /* stuff */
> #endif
> translates /* stuff */ only if exp evaluates to non-zero,
> and zero never evaluates to non-zero, /* stuff */ is never
> translated if exp == 0.

What are the contraints on the composition of the "stuff"
within the confines of the #if 0/#endif brackets?

Does it have to be theoretically parseable C ?

- Larry Weiss

Michael Rubenstein

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
On Sat, 15 Aug 1998 06:45:15 -0500, Larry Weiss <l...@airmail.net>
wrote:

It must be parsable to preprocessor tokens; otherwise it needn't be
syntactically correct. The main effect of this is that you can't use
unpaired appostrophes or quotes.

#if 0
this is legal in excluded code
#endif

#if 0
but this isn't legal
#endif

also comments must be well formed, end of line continuations (\) are
respected, and preprocessor directives must be sufficiently
well-formed to properly nest. For example,

#if 0
#if 1
#endif

does not terminate the excluded code since the preprocessor recognizes
the nested #if. However,

#if 0
#if foobar +
#endif
#endif

if OK since the nested #if is only parsed through the name -- the
expression is not parsed beyond recognizing preprocessor tokens.
--
Michael M Rubenstein

Sunil Rao

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
Larry Weiss <l...@airmail.net> wrote, and I reply...

>Martin Ambuhl wrote:
>> #if exp
>> /* stuff */
>> #endif
>> translates /* stuff */ only if exp evaluates to non-zero,
>> and zero never evaluates to non-zero, /* stuff */ is never
>> translated if exp == 0.
>
>What are the contraints on the composition of the "stuff"
>within the confines of the #if 0/#endif brackets?
>
>Does it have to be theoretically parseable C ?

It gets taken out by the preprocessor, right? So I'd guess that it would
never actually get to the compilation stage proper... so all you need is
a bunch of valid preprocessor tokens. I'd be wary of leaving any
unmatched apostrophes and stuff... :)

Pete Becker

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
Sunil Rao wrote:
>
> It gets taken out by the preprocessor, right? So I'd guess that it would
> never actually get to the compilation stage proper... so all you need is
> a bunch of valid preprocessor tokens. I'd be wary of leaving any
> unmatched apostrophes and stuff... :)

Why? The preprocessor doesn't care about apostrophes, quotes, comments,
etc. All it looks at is lines the begin with '#'.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com

John Kugelman

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
Pete Becker wrote:
>
> Sunil Rao wrote:
> >
> > It gets taken out by the preprocessor, right? So I'd guess that it would
> > never actually get to the compilation stage proper... so all you need is
> > a bunch of valid preprocessor tokens. I'd be wary of leaving any
> > unmatched apostrophes and stuff... :)
>
> Why? The preprocessor doesn't care about apostrophes, quotes, comments,
> etc. All it looks at is lines the begin with '#'.

That's blatantly wrong. The pre-processor does other things beside
process directives. It removes comments, removes backslash-newline
pairs, etc. And to do this, it must split the source code file into
pre-processing tokens. If it didn't care about quotes and apostrophes
it would destroy any source code with a line like:

puts ("/* begins comments in C.");

--
John Kugelman. kuge...@mnsinc.com

I believe we can change anything.
I believe in my dream.
- Joe Satriani

Martin Ambuhl

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to

Larry Weiss wrote in message
<1EF3475A4B802374.03D7CAF5...@library-proxy.airnew
s.net>...

|Martin Ambuhl wrote:
|> #if exp
|> /* stuff */
|> #endif
|> translates /* stuff */ only if exp evaluates to non-zero,
|> and zero never evaluates to non-zero, /* stuff */ is never
|> translated if exp == 0.
|
|What are the contraints on the composition of the "stuff"
|within the confines of the #if 0/#endif brackets?
|
|Does it have to be theoretically parseable C ?
=========
It must be made of legal preprocessing tokens. This is not quite
the same thing as theoretically parseable.


Aaron Crane

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
In article <6r4dgg$h...@news-central.tiac.net>,

"Martin Ambuhl" <mam...@tiac.net> writes:
> Larry Weiss wrote in message
> <1EF3475A4B802374.03D7CAF5...@library-proxy.airnew
> s.net>...
> |What are the contraints on the composition of the "stuff"
> |within the confines of the #if 0/#endif brackets?
> |
> |Does it have to be theoretically parseable C ?
> =========
> It must be made of legal preprocessing tokens. This is not quite
> the same thing as theoretically parseable.

Indeed. For example, a cute example that no-one's pointed out yet is that
you can put bizarre pp-numbers in there. For example:

.0_this_is_certainly_an_unusual_number_e+

Of course, as I think other people have mentioned, you also have to make
sure that pre-processor conditionals are correctly nested within the `#if 0'
section.

--
Aaron Crane <aaron...@pobox.com> <URL:http://pobox.com/~aaronc/>

Larry Weiss

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
Aaron Crane wrote:
> "Martin Ambuhl" <mam...@tiac.net> writes:
> > Larry Weiss wrote in message
> > |What are the contraints on the composition of the "stuff"
> > |within the confines of the #if 0/#endif brackets?
> > =========
> > It must be made of legal preprocessing tokens.
>
> Indeed. For example, a cute example that no-one's pointed out yet
> is that you can put bizarre pp-numbers in there. For example:
> .0_this_is_certainly_an_unusual_number_e+
> Of course, as I think other people have mentioned, you also have to
> make sure that pre-processor conditionals are correctly nested
> within the `#if 0' section.

How about "escape sequences" such as used in some laser printers?
Can they be used within the #if 0/#endif brackets?

Also, are #include's expanded if located within #if 0/#endif brackets?

- Larry Weiss

Sunil Rao

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
Pete Becker <peteb...@acm.org> wrote, and I reply...

>> It gets taken out by the preprocessor, right? So I'd guess that it would
>> never actually get to the compilation stage proper... so all you need is
>> a bunch of valid preprocessor tokens. I'd be wary of leaving any
>> unmatched apostrophes and stuff... :)
>
>Why? The preprocessor doesn't care about apostrophes, quotes, comments,
>etc. All it looks at is lines the begin with '#'.

Erm... /* within string constants???

Pete Becker

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
John Kugelman wrote:
>
> Pete Becker wrote:
> >
> > Sunil Rao wrote:
> > >
> > > It gets taken out by the preprocessor, right? So I'd guess that it would
> > > never actually get to the compilation stage proper... so all you need is
> > > a bunch of valid preprocessor tokens. I'd be wary of leaving any
> > > unmatched apostrophes and stuff... :)
> >
> > Why? The preprocessor doesn't care about apostrophes, quotes, comments,
> > etc. All it looks at is lines the begin with '#'.
>
> That's blatantly wrong. The pre-processor does other things beside
> process directives. It removes comments, removes backslash-newline
> pairs, etc. And to do this, it must split the source code file into
> pre-processing tokens. If it didn't care about quotes and apostrophes
> it would destroy any source code with a line like:
>
> puts ("/* begins comments in C.");

Why? There are no preprocessing directives in that line. The
preprocessor simply passes it through unchanged.
Lets look a little more carefully at the description of the phases of
translation in the standard:

Phase 1 maps physical source file characters to the source character set
and process trigraph sequences.

Phase 2 splices source lines.

Phase 3 decomposes the source file into preprocessing tokens and
sequences of white spaces, and replaces comments with white space.

Phase 4 handles preprocessing directives.

Now, agreed, it's possible to consider all four phases as "the
preprocessor", but that doesn't make it "blatantly wrong" to consider
phase 4 to be "the preprocessor". For example, I've seen some standalone
preprocessors that leave comments in the code.
In any event, an unmatched apostrophe does not affect the validity of
any preprocessing directive that precedes or follows it. If you
disagree, please give an example.

Eric Amick

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
Larry Weiss <l...@airmail.net> wrote:
> Aaron Crane wrote:
>> "Martin Ambuhl" <mam...@tiac.net> writes:
>> > Larry Weiss wrote in message
>> > |What are the contraints on the composition of the "stuff"
>> > |within the confines of the #if 0/#endif brackets?
>> > =========
>> > It must be made of legal preprocessing tokens.
>>
>> Indeed. For example, a cute example that no-one's pointed out yet
>> is that you can put bizarre pp-numbers in there. For example:
>> .0_this_is_certainly_an_unusual_number_e+
>> Of course, as I think other people have mentioned, you also have to
>> make sure that pre-processor conditionals are correctly nested
>> within the `#if 0' section.

> Also, are #include's expanded if located within #if 0/#endif brackets?

No, at least not according to the C9X draft. I'd be very surprised if
that's different from the current standard.

--
Eric Amick
Columbia, MD
eam...@clark.net

Lawrence Kirby

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
In article <35D5EE90...@acm.org> peteb...@acm.org "Pete Becker" writes:

>John Kugelman wrote:
>>
>> Pete Becker wrote:
>> >
>> > Sunil Rao wrote:
>> > >
>> > > It gets taken out by the preprocessor, right? So I'd guess that it would
>> > > never actually get to the compilation stage proper... so all you need is
>> > > a bunch of valid preprocessor tokens. I'd be wary of leaving any
>> > > unmatched apostrophes and stuff... :)
>> >
>> > Why? The preprocessor doesn't care about apostrophes, quotes, comments,
>> > etc. All it looks at is lines the begin with '#'.
>>
>> That's blatantly wrong. The pre-processor does other things beside
>> process directives. It removes comments, removes backslash-newline
>> pairs, etc. And to do this, it must split the source code file into
>> pre-processing tokens. If it didn't care about quotes and apostrophes
>> it would destroy any source code with a line like:
>>
>> puts ("/* begins comments in C.");
>
> Why? There are no preprocessing directives in that line.

Consider

#if 0


puts ("/* begins comments in C.");

#endif

compared with

#if 0


"puts ("/* begins comments in C.");

#endif

Detecting string literals is part of the pp-tokenisation process, it needs
to do this to determine whether the /* really does start a comment. If it
does that will extend past the #endif eliminating that directive. Therefore
the code between the #if 0 and #endif does need to be pp-tokenised.

>The
>preprocessor simply passes it through unchanged.
> Lets look a little more carefully at the description of the phases of
>translation in the standard:
>
>Phase 1 maps physical source file characters to the source character set
>and process trigraph sequences.
>
>Phase 2 splices source lines.
>
>Phase 3 decomposes the source file into preprocessing tokens and
>sequences of white spaces, and replaces comments with white space.
>
>Phase 4 handles preprocessing directives.
>
> Now, agreed, it's possible to consider all four phases as "the
>preprocessor", but that doesn't make it "blatantly wrong" to consider
>phase 4 to be "the preprocessor".

In fact the preprocessor is usually considered to cover phases 1-6.

>For example, I've seen some standalone
>preprocessors that leave comments in the code.

The standard doesn't define a textual preprocessor output format just
as it doesn't define object file formats. However even if you defined
``preprocessing'' to be just phase 4 in some standalone way, for a
conforming implementation it would still have to have been fed data that
has had phases 1, 2 and 3 applied so no comments would reach it. Therefore
to write comments to a data log the preprocessor must have control
of at least phase 3 as well i.e. have access to the data before
comments are removed.

> In any event, an unmatched apostrophe does not affect the validity of
>any preprocessing directive that precedes or follows it. If you
>disagree, please give an example.

See above. You can replace string literals with character constants if you
wish (remember multi-character character constants are allowed).

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------


0 new messages