expressions and #if

craig at BBN-LABS-B.ARPA craig at BBN-LABS-B.ARPA
Tue Jul 10 21:59:00 AEST 1984


From:  Craig Partridge <craig at BBN-LABS-B.ARPA>


[I don't believe I have seen this issue discussed before, though I was
off the net for a while].

    I have been working a little bit on extending a program that reads
C programs and replaces all #ifdef'ed code with the code for which
the condition applies.  I.e. given the code
-------------------
#ifdef FOO
    a = b;
#else
    b = a;
#endif
-------------------
and FOO not defined, the program replaces all this stuff with simply
-------------------
    b = a;
-------------------
My extension is to add support for the #if statement, and I have run
into several definitional problems.  The problems come from several
different directions -- I will try to break them up logically.

    The definition of #if is that it evaluates a constant-expression
(K&R 12.3 and 15).  But constant-expression is not very well defined.
First, it is only defined for case, array bounds and initializers.
The definitions differ between the first two and initializers.  Since
initializers seem to be viewed as a very exceptional case, I have
assumed that #if is akin to case or array bounds.  In these cases
a constant-expression is defined as involving

	"only integer constants, character constants, and sizeof
	expressions, possibly connect by the binary operators

		+ - * / % & | ^ << >> == != < > <= >=

	or by the unary operators

		- ~

	or by the ternary operator

		?:

	Parentheses can be used for grouping, but not for function calls"

O.K.  now for the problems: 

    (1) the unary operator ! is not included in the list of legitimate
    operators.  This makes #if much less useful.  Any views on whether
    this is intentional or just a typo?  Same question for && and ||.

    (2) The Berkeley code seems to include a new macro operator
    defined(x) which returns 1 if x is defined, 0 otherwise.
    Is this now a generally accepted feature or just a Berkeley extension?

    (3) the fact that two types of constants raises some interesting
    troubles.  Is one required to support type casts in the
    constant-expression?
    
    (4) Related to (3), must sizeof(expression) be supported?  If
    so can "expression" be any expression or just a constant-expression?
    Can "expression" contain type casts?

    (5) /lib/cpp on 4.2 supports a few features that are not mentioned
    in the standards.  For example, the comma operator is supported in
    the constant-expression.  Are there other extensions people know
    of -- are they generally accepted?

    (6) A nice definitional problem to finish off the list.
    #if is clearly a preprocessor statement.  But there is no
    definition in the manual of how much the preprocessor is
    supposed to know about.  The manual says simply that the preprocessor
    is "capable of macro substitution, conditional compilation and
    inclusion of include files."  No mention is made of expression
    handling, although #if clearly requires it.  Just how bright
    is the preprocessor required to be?

Interested to hear people's views,

Craig Partridge
craig at bbn-unix  (ARPA)
bbncca!craig	(USENET)



More information about the Comp.lang.c mailing list