[comp.lang.c] Compiler bug

njk@freja.diku.dk (Niels J|rgen Kruse) (12/15/88)

Consider this little one liner:
-------- foo.c --------
int foo = 1 && 0;
------ end foo.c ------

On a Bsd 4.3 VAX 785, cc complains :
"foo.c", line 1: illegal initialization
and likewise does lint :
foo.c:
foo.c(1): illegal initialization
foo defined( foo.c(1) ), but never used

On a Xenix286 intel sys310, cc compiles it nicely, but lint
complains :

foo.c
==============
(1)  warning: constant in conditional context
(1)  illegal initialization


==============
name defined but never used
    foo         foo.c(1)

So 3 out of 4 get it wrong. This bug seems to bee contagious.

-----
Niels J|rgen Kruse
njk@freja.dk
DIKU, Copenhagen, Denmark

guy@auspex.UUCP (Guy Harris) (12/17/88)

>So 3 out of 4 get it wrong.

3 out of 4 are based on PCC (4.3BSD C compiler, 4.3BSD "lint", and, I
suspect, Xenix "lint").  That's the nice thing about portable
software, the bugs port too....

The compiler problem may be due to PCC's incredible sensitivity to tiny
perturbations in the order in which various operations are done on the
expression trees; if you change one \s-22little tiny thing\s0 you can
end up with expressions not being evaluated at compile time to the
maximum extent possible.

I think a fix for the "lint" problem was posted a long time ago; if you
consider it dumb that it complains about an expression being constant in
a context where only constant expressions are allowed, it'll clean this
problem up.  Part of the reason why "lint" checks for constants in a
conditional context may be to catch things like

	if (a & MASK == VALUE)

which are equivalent to

	if (0)

since MASK != VALUE; what was desired was

	if ((a & MASK) == VALUE)

The nasty part is that sometimes a "constant in conditional context" is
caused by an error, and other times it's deliberate and desired; as one
version of the "lint" manual page stated, "There are some things you
just *can't* get 'lint' to shut up about."

scs@adam.pika.mit.edu (Steve Summit) (12/18/88)

In article <4279@freja.diku.dk> njk@freja.diku.dk (Niels Jurgen Kruse) writes:
>Consider this little one liner:
>-------- foo.c --------
>int foo = 1 && 0;
>------ end foo.c ------
>On a Bsd 4.3 VAX 785, cc complains :
>"foo.c", line 1: illegal initialization
[several other failures described]
>So 3 out of 4 get it wrong. This bug seems to bee contagious.

In article <733@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes:
>3 out of 4 are based on PCC...
>The compiler problem may be due to PCC's incredible sensitivity to tiny
>perturbations in the order in which various operations are done on the
>expression trees...

Or, more likely, it has to do with the unfortunate description of
constant expressions in the original K&R (first edition, section
15, page 211):

	...the expression can involve... the binary operators

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

	or... the unary operators

		-  ~

	or... the ternary operator

		? :

Ritchie's original pdp11 C compiler also reports "illegal
initialization" for an initialization involving &&.

Harbison and Steele note (second edition, p. 188) that "the
original description of C did not mention that the operator ! is
allowed in constant expressions, but this obviously was an
oversight or a typographical error."  Their list of operators
allowed in constant expressions includes && and ||, without
comment.

K&R, second edition (section A7.19, p. 209) contains no explicit
list of operators, implying that all (other than obvious
exceptions such as unary &) are now allowed.

Before rejecting the historical restriction on && and ||
out-of-hand, recall that && and || are somewhat different from
the other binary operators: they affect control flow, in that
evaluation of the right-hand-side is short-circuited if its value
will not affect the result.  This fact does not justify their
being disallowed in constant expressions, but it makes it easier
to understand why an implementation might (perhaps inadvertently)
do so.  Since "control flow" is meaningless in constant
expressions, the handling of && and || in constant expressions
could be different (read "nonexistent"), as opposed to normal
expressions.  (Of course, the interpretive handling of constant
expressions is already pretty different from the code generation
performed for normal expressions.)

Another illustration of boolean foibles in constant expressions
is something like

	#define a 0
	#if a == 0 || 4 / a < 2

which causes some (many?) cpp's to abort with a divide by 0
fault.

                                            Steve Summit
                                            scs@adam.pika.mit.edu

mat@mole-end.UUCP (Mark A Terribile) (12/20/88)

> -------- foo.c --------
> int foo = 1 && 0;
> ------ end foo.c ------
> 
> On a Bsd 4.3 VAX 785, cc complains :
> "foo.c", line 1: illegal initialization
> 
> On a Xenix286 intel sys310, cc compiles it nicely, but lint
> (1)  warning: constant in conditional context
> (1)  illegal initialization

Actually, the compilers are right, more or less.  According to the reference
manual in the back of K&R (I haven't yet got the dpANS for C) && and || are
NOT among the operators which may be used to compose constant expressions,
so the messages about illegal initializations make sense.  The warning about
the illegal constant sounds bogus; I suspect that the Xenix compiler is trying
to tell you that it thinks that if you really mean that you should do it with
the preprocessor.

Now then, how to do what you want to do?  Well, among the operators that
*can* be used to compose constant expressions is  ?: .

For  a && b , use  a ? b : 0 .
For  a || b , use  a ? 1 : b .

The Xenix compiler will probably still bless you with a warning.
-- 

(This man's opinions are his own.)
From mole-end				Mark Terribile

friedl@vsi.COM (Stephen J. Friedl) (12/21/88)

Somebody posts this code that fails one a 4BSD VAX:

> int foo = 1 && 0;       /* "foo.c", line 1: illegal initialization */

In article <126@mole-end.UUCP>, mat@mole-end.UUCP (Mark A Terribile) writes:
> According to the reference manual in the back of K&R (I haven't yet got
> the dpANS for C) && and || are NOT among the operators which may be used
> to compose constant expressions, [...]

The dpANS [May88] says this is OK.  Look in the Language Syntax Summary
in Appendix A and focus on `initializer' (bottom of p 180).  Follow it up
the path and you'll hit || and &&.  I didn't see any constraints that
would prevent this, and my compiler takes it as well.

     Steve

-- 
Stephen J. Friedl        3B2-kind-of-guy            friedl@vsi.com
V-Systems, Inc.                                 attmail!vsi!friedl
Santa Ana, CA  USA       +1 714 545 6442    {backbones}!vsi!friedl
Nancy Reagan on my new '89 Mustang GT Convertible: "Just say WOW!"