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!"