I came across this must-read article. I was a maintenance programmer for 29 years and I've come across many of the deadly sins that he discusses and maybe even one or two that he does not. How to Write Unmaintainable Code by Roedy Green.
Yeah, definitely a must-read! It makes you laugh and cry. There are things in there that just sound so outrageous and deliberately vicious against the maintainers. And it makes you laugh until you realize that you've seen exact examples of that in real-life production code.... and it really turns bitter when you realize you've written code like that before.
I can also easily think of a few main-stream production-grade projects that easily obey at least half of those rules for writing unmaintainable code (cough.. cough.. LLVM/Clang cough.. cough..).
At one time, I used to write a lot of FORTRAN code. In FORTRAN, many of these gems were ingrained in the way you were taught (i,j,k as integer variables, etc.). As I read through this, I had deja vu all over again with some of the code I've come across. However, the height of obfuscation is not making the code look obfuscated. That is a black art unto itself. ;-)
I did maintenance/development (mostly maintenance) with FORTRAN code for 15 years. I was really pissed when I found
INTEGER NINE /5/
but the worst ever code was
SUBROUTINE READALL(UNIT,BUFF,*,*,IFIRST) C*TTL READALL READ FROM ANYTHING C C C C THIS SUBROUTINE IS USED FOR READING COMPRESSED OR UNCOMPRESSED C DATA INPUT FILES FROM LFC 'UNIT' INTO 80 BYTE ARRAYY BUFF. C END RETURNS TO FIRST RETURN, ERROR RTETURNS TO SECOND C IFIRST IS LOGICAL WHICH CALLER PROVIDES TRUE ON C FIRST READ OFF OF THIS ALLOCATION OF THIS LFC, ELSE FALSE C*PGMXX READALL SAVD TOOLS FS$READA ON 07/23/80 17:43:51 01819B00R01 LOGICAL IFIRST INTEGER*1 BUFF(80) INTEGER*4 UNIT INTEGER*1 BYTE(120,2) C C INTEGER*1 IN(2)/2*0/,ISP(2)/2*0/,ITX(2)/2*0/,NB(2)/2*0/ INTEGER*1 NBT(2)/2*1/ INTEGER*1 KCR/ZBF/,KLR/Z9F/ INTEGER*1 EOR/ZFF/ INTEGER*2 NSEQ(2)/2*0/,ITY(6),ISEQ(60,2),ICKS(60,2) INTEGER*4 LFC(2)/2*0/ INTEGER*4 K,N,IERR,IN0,ISP0,ITX0,NB0,IS,I,ISUM,J C C EQUIVALENCE (BYTE(3,1),ICKS(1,1)),(BYTE(5,1),ISEQ(1,1)) C C IF(.NOT.IFIRST) GO TO 21 DO 19 K=1,2 IN(K) = 0 ISP(K) = 0 ITX(K) = 0 NB(K) = 0 NBT(K) = 1 NSEQ(K) = 0 LFC(K) = 0 19 CONTINUE 21 CONTINUE DO 101 N=1,2 IF (UNIT.EQ.LFC(N)) GO TO 103 IF (LFC(N).EQ.0) GO TO 102 101 CONTINUE GO TO 94 102 LFC(N) = UNIT CALL W:PDEV(UNIT,ITY) NBT(N) = 1 IF (ITY(3).GE.4.AND.ITY(3).LE.6) NBT(N)=2 103 IERR = 0 IN0 = IN(N) ISP0 = ISP(N) ITX0 = ITX(N) NB0 = NB(N) 1 IF (IN0.NE.0) GO TO 8 2 CALL BUFFERIN(UNIT,0,BYTE(1,N),30) CALL M:WAIT(UNIT) CALL STATUS(UNIT,IS,NB0) IF (IS-3) 3,80,90 3 IF (BYTE(1,N).EQ.KCR.OR.BYTE(1,N).EQ.KLR) GO TO 6 NB0 = NB0*NBT(N) DO 4 I=1,NB0 IF (BYTE(I,N).EQ.10.OR.BYTE(I,N).EQ.13) BYTE(I,N) = 1R 4 BUFF(I) = BYTE(I,N) IF (NB0.GE.80) GO TO 20 I = I+1 DO 5 I=I,80 5 BUFF(I) = 1R GO TO 20 6 NB0 = BYTE(2,N) IF (NB0.GT.114) GO TO 91 ISUM = 0 DO 7 I=1,NB0 7 ISUM = ISUM+BYTE(I+6,N) IF (ISUM.NE.ICKS(1,N)) GO TO 92 IF (ISEQ(1,N).NE.NSEQ(N)) GO TO 93 NSEQ(N) = NSEQ(N)+1 IN0 = 7 8 DO 16 I=1,80 IF (ISP0.NE.0) GO TO 9 IF (ITX0.NE.0) GO TO 12 IF (BYTE(IN0,N).EQ.EOR) GO TO 9 ISP0 = BYTE(IN0,N) IF (ISP0.GT.81-I) GO TO 91 IN0 = IN0+1 GO TO 10 9 ISP0 = ISP0-1 10 IF (ISP0.EQ.0) GO TO 11 BUFF(I) = 1R GO TO 16 11 IF (BYTE(IN0,N).EQ.EOR) GO TO 9 ITX0 = BYTE(IN0,N) IF (ITX0.GT.81-I) GO TO 91 IN0 = IN0+1 12 BUFF(I) = BYTE(IN0,N) IF (BUFF(I).EQ.10.OR.BUFF(I).EQ.13) BUFF(I) = 1R ITX0 = ITX0-1 13 IN0 = IN0+1 IF (IN0.LE.NB0+6) GO TO 16 CALL BUFFERIN(UNIT,0,BYTE(1,N),30) CALL M:WAIT(UNIT) CALL STATUS(UNIT,IS,NB0) IF (IS-3) 14,80,90 14 IF (BYTE(1,N).NE.KCR.AND.BYTE(1,N).NE.KLR) GO TO 91 NB0 = BYTE(2,N) IF (NB0.GT.114) GO TO 91 ISUM = 0 DO 15 J=1,NB0 15 ISUM = ISUM+BYTE(J+6,N) IF (ISUM.NE.ICKS(1,N)) GO TO 92 IF (ISEQ(1,N).NE.NSEQ(N)) GO TO 93 NSEQ(N) = NSEQ(N)+1 IN0 = 7 16 CONTINUE IF (BYTE(IN0,N).NE.EOR) GO TO 91 ISP0 = 0 IF (ITX0.NE.0) GO TO 91 IN0 = IN0+1 IF (IN0.GT.NB0+6) IN0 = 0 IF (BYTE(1,N).EQ.KLR.AND.IN0.EQ.0) NSEQ(N) = 0 20 IN(N) = IN0 ISP(N) = ISP0 ITX(N) = ITX0 NB(N) = NB0 RETURN 80 NSEQ(N) = 0 IN(N) = ISP(N) = ITX(N) = 0 RETURN 1 90 IERR = 1 91 IERR = IERR+1 92 IERR = IERR+1 93 IERR = IERR+1 94 IERR = IERR+1 IN(N) = ISP(N) = ITX(N) = 0 BUFF(1) = IERR RETURN 2 END
The vendor (in order to save space on a 300 MB disk) wrote this gem for their line editor to read from (somewhat) compressed text files. I eventually rewrote it but it took days to recode (most of the time was taken up in testing). Dontcha just love the extensive documentation?
Edited by Reverend Jim
@Jim, wow this code is a real piece of work. My head hurt just looking at all those labels and gotos. Now, I do use gotos in my C code in the Linux kernel, but that's pretty much the standard way to write drivers in Linux. Still, none of that even compares to the gem you've just shared.
Thanks for reminding me just how bad code can get.