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

Preprocessor constant folding

31 views
Skip to first unread message

Glen Blankenship

unread,
Nov 6, 1994, 3:52:01 PM11/6/94
to
In another thread in this group, people have been discussing (once again)
the advisability of using #defines such as:

#define TRUE (0==0)
#define FALSE (0!=0)

Now, leaving aside the question of whether or not defining TRUE and FALSE
is a good idea, and ignoring, for the moment, the fact that #defines like
the above are a silly waste of time, what I'm wondering is:

Does the ANSI/ISO standard actually *require* a conforming implementation
to reduce statements such as the above to constants, or is it possible
that some naive (but still conforming) implementation could actually
generate code that explicitly performs the specified comparisons every
time the programmer uses TRUE and FALSE in his code?

In other words, is (0==0) strictly equivalent to a constant 1, or
is it possible that it could actually produce slower, less efficient
code?

(And a trivia question: Why is it called "constant folding"?)

---
Glen Blankenship
obo...@netcom.com
g.blan...@genie.geis.com

Paul Long

unread,
Nov 8, 1994, 5:03:14 PM11/8/94
to
In article obotherC...@netcom.com, obo...@netcom.com (Glen Blankenship)
writes:

>> In another thread in this group, people have been discussing (once again)
>> the advisability of using #defines such as:
>>
>> #define TRUE (0==0)
>> #define FALSE (0!=0)
[snip]

>> Does the ANSI/ISO standard actually *require* a conforming implementation
>> to reduce statements such as the above to constants, or is it possible
>> that some naive (but still conforming) implementation could actually
>> generate code that explicitly performs the specified comparisons every
>> time the programmer uses TRUE and FALSE in his code?

I guess I'll respond since I first suggested this way of defining TRUE and
FALSE. (I have since recanted because so many people thought it pedantic.)
Constant folding is an optimization, and the Standard does not require any
optimizations. Therefore, an implementation may evaluate operations on
constants at run time.

However, there are a few places where a Standard C compiler _must_ evaluate a
constant expression at compile time. One is the constant expression of a
case statement. "No two of the case constant expressions in the same switch
statement shall have the same value after conversion," 6.6.4.2. The only
practical way to do this is to fold each case statement's constant expression
down to a single constant and then compare it to the other case statements'
constants. Constant-expression evaluation must also be performed on the size
expression in an array declarator. "The expression delimited by [ and ]
(which specifies the size of an array) shall be an integral constant
expression that has a value greater than zero," 6.5.4.2. Again, the only
practical way to
determine whether the value is greater than zero is to first perform constant
folding.

Now, having evaluated a constant expression at compile time, I suppose an
implementation could then turn around and generate code for the original,
unfolded expression. I can't imagine one doing that, though, because there
would be no benefit.

So, if a compiler performs constant folding on case and array-size
expressions it would probably be more work for it to _not_ perform it
everywhere else. Because constant folding is easy to implement, takes little
time to perform, and is a space _and_ time optimization, I always assume that
the compiler writer did the right thing. I also assume that one can never
turn off constant folding with, for example, a command-line option such as -g
because the compiler must evaluate constant expressions at compile time even
when no other optimizations are performed.

>> In other words, is (0==0) strictly equivalent to a constant 1, or
>> is it possible that it could actually produce slower, less efficient
>> code?

(0==0) is "equivalent" in that it always evaluates to 1, but an
implementation is free to evaluate the expression at run time. This is a
quality-of-implementation issue.

>> (And a trivia question: Why is it called "constant folding"?)

Take a piece of paper and fold it in half. It is still the same piece of
paper, but it occupies half the area. Likewise, take a binary operator with
constant operands and replace it (fold it) with the result of the operation.
It still represents tha same value, but it occupies less code space.


BTW, regarding the subject of your article, constant folding would probably
be done in the parser, not the preprocessor. Having said that, the Standard
does not require a "preprocessor." It talks about preprocessor directives,
tokens, etc., but nowhere does it describe the behavior of a preprocessor.

Paul...@ortel.org


Sent from Oregon Telcom

Lawrence Kirby

unread,
Nov 9, 1994, 3:51:45 PM11/9/94
to
In article <obotherC...@netcom.com>
obo...@netcom.com "Glen Blankenship" writes:

>Does the ANSI/ISO standard actually *require* a conforming implementation
>to reduce statements such as the above to constants,

Yes. The compiler must treat (0==0) as an integer constant expression
with value 1 wherever it appears it appears in a valid place for an
integer constant expression in the source code.

>or is it possible
>that some naive (but still conforming) implementation could actually
>generate code that explicitly performs the specified comparisons every
>time the programmer uses TRUE and FALSE in his code?

That is also possible because C allows the compiler to do anything so
long as the final result is correct. It could legeally evaluate any instance
of the constant 1 as (0==0) if it felt like it. However a C compiler has to
be able to fully evaluate an integer constant expression at compile time
in certain situations such as array definitions and it would be a pretty
worthless compiler that didn't extend that to all integer constant
expressions.

>In other words, is (0==0) strictly equivalent to a constant 1, or
>is it possible that it could actually produce slower, less efficient
>code?

The C standard has nothing to say about efficiency, it merely defines
what code is 'legal' and what the results of executing such 'legal'
code should be. It may be that on a certain archetecture executing the
equivalent instruction(s) to (0==0) is the fastest way of loading the
value 1 into a register (not likely I grant you, but compare that to
reg ^= reg which is often the fastest/shortest way of loading 0 into a
register).

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

Mike Rubenstein Phoenix Contract

unread,
Nov 11, 1994, 8:22:15 AM11/11/94
to
Glen Blankenship (obo...@netcom.com) wrote:
> In another thread in this group, people have been discussing (once again)
> the advisability of using #defines such as:

> #define TRUE (0==0)
> #define FALSE (0!=0)

> Now, leaving aside the question of whether or not defining TRUE and FALSE
> is a good idea, and ignoring, for the moment, the fact that #defines like
> the above are a silly waste of time, what I'm wondering is:

> Does the ANSI/ISO standard actually *require* a conforming implementation
> to reduce statements such as the above to constants, or is it possible
> that some naive (but still conforming) implementation could actually
> generate code that explicitly performs the specified comparisons every
> time the programmer uses TRUE and FALSE in his code?

> In other words, is (0==0) strictly equivalent to a constant 1, or
> is it possible that it could actually produce slower, less efficient
> code?

It's strictly equivalent as far as the semantics go. The compiler is required
to accept (0==0) wherever a constant is permitted. For example,

int foo[(0==0)];

declares foo as an array of 1 int. See ISO 6.4.

There is no such a requirement for code generation. The compiler could
produce different code as far as the standard is concerned. But this is very
unlikely. In order to conform, the compiler must recognize that 0==0 is
a constant, so it would be silly to treat it different from 1 when generating
code.

--
Mike Rubenstein

0 new messages