patc (03/15/83)
I have come across a funny in the PCC compiler that I would like to know about. A statement was mis-coded as: a && b *= c ; No error message was given. The code that was produced showed that the compiler compiled the statement as: if ( a ) b *= c ; I thought the && operator had a higher precedence than assignment and the result should have been equivalent to: ( a && b ) *= c ; If I code the statement with explicit parens then I get the error message "lvalue required" which is what I expected. Anybody have any idea why this is like this and is this the way it's suppose to work or is it a bug? Reply by mail to [cbsog,decvax,ihnss,puree,ucbvax]!teklabs!tekmdp!patc [ucbcad,iddic]!tektronix!patc patc@tektronix CSNET Thanks.
porges (03/20/83)
#R:bronze:-50100:inmet:5000002:000:490 inmet!porges Mar 18 17:48:00 1983 I don't know if you could really call a && b *= c (or whatever) a bug. The precedence levels are confusing, but all that's happened is that the compiler found a legal parse. If the legal parse implies that the default precedence is not applicable, too bad. The precedence levels server to disambiguate the parse, not restrict it. Or am I wrong again? -- Don Porges ...harpo!inmet!porges ...hplabs!sri-unix!cca!ima!inmet!porges ...yale-comix!ima!inmet!porges
jdd (03/23/83)
The behavior in PCC on: a && b *= c is (possibly) serendipitous but ultimately indicative of a compiler bug. Parsing it as: a && (b *= c) does not reflect the correct operator precendences. If you believe that PCC is magically "doing the right thing", tell me why it won't compile: int *a, b, c; ... ... a+b[c] ... since interpreting the expression as: ... (a+b)[c] ... would "make sense". No compilers (i.e., no languages) I know of overload the syntax in this way; a little thought suggests that doing so could cause as much harm as good; most of my coding errors have some "interpretation", but probably not the one I intended. Cheers, John ("Let's All Program In Lisp Instead") DeTreville Bell Labs, Murray Hill
bernie (03/30/83)
Yes, the statement a && b *= c; is a curious thing. Nevertheless, it makes sense as if (a) b *= c; since the compiler is really regarding it as a && (b *= c); and will only evaluate the (b *= c) part if the a part is non-zero. That is, if a is false, there's no need to evaluate the other operand of && since the overall value of the expression is already known. --Bernie Roehl ...decvax!watmath!watarts!bernie
johnl (04/01/83)
#R:watarts:-176200:ima:15900004:000:680 ima!johnl Mar 31 11:32:00 1983 Let's drive a stake through the heart of this one, once and for all. a && b *= c; (1) should not be the same as: if (a) b *= c; (2) because, since && binds tighter than *=, the only correct parse is: (a && b) *= c; (3) which is semantically meaningless. PCC interprets it as (2), due to a bug in yacc. (PCC uses a yacc parser, if you didn't know.) Yacc is unlikely to be fixed, since it is a fairly obscure implementation of the LALR parser generation algorithm which is itself pretty confusing. John Levine, decvax!yale-co!jrl, ucbvax!cbosgd!ima!johnl, {research|alice|rabbit|floyd|amd70}!ima!johnl
tjt (04/01/83)
Some of this depends on what you would like '&&' to mean as well as how you would like assignment to behave (note the key phrase "would like"). One possibility is for: a && b to be equivalent to: a ? a : b Without a re-evaluation of a. i.e. another of C syntactic devices to trick the programmer into doing most of the optimizing. Then the question becomes whether the statement a ? a : b *= c; should make any sense. It could, if you distribute the expression through the conditional, and make it equivalent to: if (a) a *= c; else b *= c; In the C reference manual: a && b is defined as equivalent to (although not in so many words): a ? 1 : ( b ? 1 : 0 ) In addition, the '?' operator does yield a lvalue, but there's always "what if ...".
grahamr (04/04/83)
I, too, want this argument to end, but without any mud slung at yacc. With all due respect, there is no yacc bug. We were all brought up on appendix A of the yacc manual, where there is only one set of productions for an "expression". The C language is not this way; it has lvalues to deal with AND THEY ARE *SYNTACTICALLY* DIFFERENT FROM SIMPLE EXPRESSIONS. This is the fragment we are dealing with: expr : expr ANDAND expr | lvalue ASSIGN expr | primary ; primary : ID ; lvalue : ID ; The input is "ID ANDAND ID ASSIGN ID". Please note that the phrase "ID ANDAND ID" cannot be reduced to "lvalue". Look in the C Reference Manual and you will find that the same is true there. This means that the parser simply will not do this reduction. This characteristic of LR parsers is supposed to be a feature. Precedence rules are invoked when there are two or more legal parses. That is not happening here and therefore the precedence rules are not being invoked. On the subject of cdecl: We are working on the problem. If you don't have it by 4/8, send me mail or give me a call and I'll put you on my bulk mailing list. Graham Ross Tektronix, Inc. (ucbvax|decvax)!teklabs!tekmdp!grahamr (503) 629-1953
crc (04/06/83)
Sorry John, (a && b) is not an Lvalue and therefore can never be the address of the result of an assignment. Try reading "The C Programming Language". An asignment must store the result somewhere, so the left side of the assignment must supply an address; ( a && b) is logical expression, True or Not True, not an address.