Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!cs.utexas.edu!ut-emx!walt.cc.utexas.edu!erlkonig From: erlkonig@walt.cc.utexas.edu (Christopher North-Keys) Newsgroups: comp.lang.c Subject: Re: C style peeve and knowing the rules Keywords: c, maze, style Message-ID: <27143@ut-emx.UUCP> Date: 29 Mar 90 11:58:11 GMT References: <2205@osc.COM> <340018@hplvli.HP.COM> <19356@megaron.cs.arizona.edu> <894@dino.cs.iastate.edu> Sender: news@ut-emx.UUCP Reply-To: erlkonig@walt.cc.utexas.edu (Christopher North-Keys) Organization: Packaging/Interconnect, M.C.C. Lines: 116 I found this "gem" on the net somewhere. This strikes me as a good example not to follow, at least in term of commenting. Parenthesization would have helped, but then again, we probably still would have wasted hours figuring out the *meaning* behind the bloody thing, and probably still wouldn't understand the main line inside the loop. Now, there are two ways of looking at this code. The first is the inevitable recollection that C actually has contests congratulating the least-readable code. The second is more subtle: I have yet to find (even in C) a decent way to express the fuctionality of the for() statement in this program, yet due to the language's flexibility the programmer managed it. His *comments* are miserable (nay, sir; they were absent), but the flexibility of a language evidenced by the creation of a new loop idiom is *very* impressive. ...No, I don't code this way either, that's not the point. As to those advocating minimalistic parenthesization, there is always the chance that one's program will be compiled on an errant compiler. The bug could take a *long* time to find. There are also instances in preprocessor macro definitions where lenient parenthesis will mangle code, and let's not forget the possibility of making a mistake -- there are over 15 levels of operator precedence in the K&R C guide. Of course there are those who will *insist* that math expressions, like program sources, are fully self documenting. Example: "Hey, you know that you don't need to comment code, don't you? You really *use* comments? But the good programmers don't *need* them, they just clutter up the code... What kind of programmer *are* you anyway --- bet you use lots of parenthesis too, don't you... What university did you say you attended?... Yeah, I'll just *bet* you did..." Even "lint" likes parenthesis, that must mean something. output: }-1.129-> ./maze 7 ._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | ._| . . ._| | |_._._. . ._|_._._._._. ._|_. ._|_._. ._| | . ._|_. | . ._._. | | ._|_| |_. | | | | ._._|_._|_._. . |_. | | | ._._| |_._._._| | ._. ._| . . |_| |_._._._. | ._|_. ._._._. | | ._. |_._. . | ._._| |_. | . ._._._. |_. | |_|_| | | | . |_._| . ._._._| ._._. ._._| | | |_| . | |_. . ._|_|_| ._._. |_._|_| . | | | | |_| |_._| | ._. . | | |_._._| | | | | |_|_. . |_| . | |_| . . ._|_. |_|_. | |_. | |_._._._|_. |_|_| ._._| ._._. ._| . . | ._|_. ._| . ._|_| |_. . | | | | | |_._._._._._._._._._|_._._._._|_._._|_._|_|_._._|_._._|_|_._._._._|_|_._._._._| |}-1.233-> ---------------original program as posted: }-1.130-> cat maze.c 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 lint maze.c maze.c ============== (1) warning: precedence confusion possible: parenthesize! (1) warning: main() returns random value to invocation environment ============== function returns value which is always ignored printf ---------------reformatted program: }-1.187-> cat ./maze+.c main() { int C; /* number of rows of cells */ char *M; char A, Z, E=40, J[40], T[40]; for(*J = A = scanf(M = "%d", &C) ; --E ; J[E] = T[E] = E) printf("._"); /* top line of first row has been printed * J holds 1,1-39, T holds 0-39, A is 1, E and Z are 0, M -> "%d" * * ONE LINE NESTED LOOP * (the loop I understand, the contents are another matter entirely) * * Z oscillates between 0 (initially) and 1. * On the end of all passes except the last, A=39, C--, "\n|" prints. * On the end of Z==1 passes, A drops, and M is printed. * On the end of passes where Z==1, M is printed. * The loop is terminated when C is dropped to 0. */ for( ; (A -= Z = !Z) || (printf("\n|"), A=39, C--) ; Z || printf(M)) /* The abuse of M requires a GCC compile flag: -fwritable-strings * * Constant: Z A J Z C T J A[J-Z] * Variable: E M[0] M[1] T[A] J[see below] * Derivations: * E <<< A[J-Z] each pass * T[E] <<< T[A] <<< A-Z \ * J[T[A]] <<< E |__only passes printing "_." * J[A-Z] <<< A / * M[Z] is set to "_." or " |". The 1st has side-effects */ M[Z] = Z[ A - ( E = A[J-Z] ) && /* seems (6<<27 < rand()) is true app. 59% of the time */ /* /-------\ //-----\ -------\ */ !C & A == T[A] | 6 << 27 < rand() || !C & !Z ? J[T[E]=T[A]] = E , J[T[A]=A-Z] = A, "_." : " |" ]; } P.S. If anyone ever does figure this puppy out...send me mail, eh? ------------------------------------/\---------------------------------------- Seo: Harp[@Mcc.Com] / \/\ ^*^ Christopher North-Keys Tha mi gu trang a'cluich. / \ \ Assoc. Systems Analyst, MCC --------------------------------(disclaimer)----------------------------------