jfh@rpp386.Dallas.TX.US (The Beach Bum) (10/07/88)
In article <751@mcrware.UUCP> jejones@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@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