possible operator precedence bug?
The Beach Bum
jfh at rpp386.Dallas.TX.US
Fri Oct 7 14:00:33 AEST 1988
In article <751 at mcrware.UUCP> jejones at mcrware.UUCP (James Jones) writes:
>A recently-posted C program that generates random mazes gives me cause to
>wonder about C operator precedence.
>
>I include the source here for reference--it's very short:
[ and I un - >'d it so I could throw some stuff at it ... ]
char*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C);
-- E; J[ E] =T
[E ]= E) printf("._"); for(;(A-=Z=!Z) || (printf("\n|"
) , A = 39 ,C --
) ; Z || printf (M ))M[Z]=Z[A-(E =A[J-Z])&&!C
& A == T[ A]
|6<<27<rand()||!C&!Z?J[T[E]=T[A]]=E,J[T[A]=A-Z]=A,"_.":" |"];}
>The inner loop of this program contains an expression, which, as far as
>I can tell after feeding through cb, has the form
>
> M[Z]=Z[<hairy expression> ? <expression>, <expression>, "_." : " |"];
This is the fully parenthised expression, as reported by "cparen". Every
one should have this sucker - just after having "cdecl".
(M[Z])=
(Z[(((A-(E=(A[J-Z])))&&(((!C)&(A==(T[A])))|((6<<27)<(rand()))))||
((!C)&(!Z)))?
((((J[(T[E])=(T[A])])=E),((J[(T[A])=(A-Z)])=A)),"_.") :
"|"])
>The question is this: why does this make it through the compiler at all?
>K&R says that the comma operator has the lowest priority, so shouldn't
>the following be required for the code to correctly parse?
> M[Z]=Z[<hairy expression> ? (<expression>, <expression>, "_.") : " |"];
> ^ ^
No, as you can see above, the grammar groups the expression in the "correct"
fashion without the explicit parentheses.
Here is a snip from a YACC grammar which conforms to the 11/9/87 ANSI Draft.
conditional_expr
: logical_or_expr
| logical_or_expr '?' expr ':' conditional_expr
;
assignment_expr
: conditional_expr
| unary_expr assignment_operator assignment_expr
;
expr
: assignment_expr
| expr ',' assignment_expr
;
As we see, conditional_expr is of a higher precedence, but the first
expression is an <expr>. So, we luck out. Watch this:
a ? b : c , d , e
becomes
((a ? b : c) , d) , e
Notice that you now get the behaviour you expected - ',' is of a
lower precendence and the left hand side groups to reflect this.
But the code of the form
a ? b , c , d : e
becomes
a ? ((b , c) , d) : e
because the grammar specifies the left hand side of ":" as a full-blown
expression. Which implies that ? :'s nest the same way as if-then-elses
do. Watch -
a ? b ? c : d : e and
v ? w : x ? y : z
becomes [ you should be able to guess this one ;-) ]
a ? (b ? c : d) : e and
v ? w : (x ? y : z)
10 points if you got it correct ...
--
John F. Haugh II (jfh at rpp386.Dallas.TX.US) HASA, "S" Division
"Why waste negative entropy on comments, when you could use the same
entropy to create bugs instead?" -- Steve Elias
More information about the Comp.lang.c
mailing list