What is spaghetti code? [closed]

2019-01-25 04:24发布

Can you post a short example of real, overdone spaghetti code, possibly saying what it does? Can you show me a little debugger's nightmare?

I don't mean IOCCC code, that is science fiction. I mean real life examples that happened to you...

Update

The focus has changed from "post some spaghetti code" to "what is exactly spaghetti code?". From a historical perspective, the current choices seem to be:

  • old Fortran code using computed gotos massively
  • old Cobol code using the ALTER statement

13条回答
Rolldiameter
2楼-- · 2019-01-25 04:48

You've asked for it, you'll get it:

This is the source of a DOS .com file that plays the Blue Danube waltz. The executable is just 176 bytes in size. Code is re-used as data and vice versa.

.286
.model tiny

g4 equ 55-48           ; removed note-decoding !
a4 equ 57-48           ; now: storing midi-notes for octaves 0..2 and convert
h4 equ 59-48           ; to 4..6 with a simple add 48.

c5 equ 60-48
d5 equ 62-48
e5 equ 64-48
g5 equ 67-48
h5 equ 71-48

c6 equ 72-48
d6 equ 74-48
e6 equ 76-48
g6 equ 79-48           ; = 00011111b

pp  equ 0              ;  c4 is not used in the walz, using it as play-pause.
EOM equ 1              ; c#4 is also available... End Of Music
                       ; warning: experts only beyond this point !

pau1 equ 00100000b     ; bitfield definitions for note-compression
pau2 equ 01000000b     ; you can or a pau to each note!
pau3 equ 01100000b

;rep1 equ 01000000b    ; rep1 is history (only used once).
;rep3 equ 11000000b    ; rep3 was never used.

rep2 equ 10000000b     ; or a rep2 to a note to play it 3 times.

drumsize equ 5

.code
org 100h

start:
                mov  ah,9
                mov  dx,offset msg
                int  21h                    ; print our headerstring

                mov  dx,0330h               ; gus midi megaem -port
                mov  si,offset music_code   ; start of music data

mainloop:

    ; get new note (melody)

                xor  bp,bp                  ; bp= repeat-counter

                lodsb                       ; get a new note
                cmp  al, EOM                ; check for end
                jne  continue
                ret

continue:
                jns  no_rep2                ; check for rep2-Bit
                inc  bp
                inc  bp                     ; "build" repeat-counter

no_rep2:
                push ax                     ; save the note for pause

    ; "convert" to midi-note

                and  al,00011111b
                jz   skip_pp                ; check pp, keep it 0
                add  al,48                  ; fix-up oktave

skip_pp:
                xchg ax,bx                  ; bl= midi-note

play_again:
                mov  cl,3
                push cx                     ; patch program (3= piano)
                push 0c8h                   ; program change, channel 9

    ; wait (cx:dx) times

                mov  ah,86h                 ; wait a little bit
                int  15h

    ; prepare drums

                dec  di                     ; get the current drum
                jns  no_drum_underflow
                mov  di,drumsize

no_drum_underflow:

    ; play drum

                push dx                     ; volume drum
                push [word ptr drumtrk+di]  ; note   drum
                mov  al,99h
                push ax                     ; play channel 10

    ; play melody

                push dx                     ; volume melody
                push bx                     ; note   melody

                dec  ax                     ; replaces dec al :)

                push ax                     ; play channel 9

    ; send data to midi-port

                mov  cl,8                   ; we have to send 8 bytes

play_loop:
                pop  ax                     ; get the midi event
                out  dx,al                  ; and send it
                loop play_loop

    ; repeat "bp" times

                dec  bp                     ; repeat the note
                jns  play_again

    ; check and "play" pause

                xor  bx,bx                  ; clear the note, so we can hear
                                            ; a pause
    ; decode pause value

                pop  ax
                test al,01100000b
                jz   mainloop               ; no pause, get next note

    ; decrement pause value and save on stack

                sub  al,20h
                push ax
                jmp  play_again             ; and play next drum

; don't change the order of the following data, it is heavily crosslinked !
music_code      db pp or rep2

                db g4 or rep2 or pau1
                db h4 or pau1, d5 or pau1, d5 or pau3
                db d6 or pau1, d6 or pau3, h5 or pau1, h5 or pau3

                db g4 or rep2 or pau1
                db h4 or pau1, d5 or pau1, d5 or pau3
                db d6 or pau1, d6 or pau3, c6 or pau1, c6 or pau3

                db a4 or rep2 or pau1
                db c5 or pau1, e5 or pau1, e5 or pau3
                db e6 or pau1, e6 or pau3, c6 or pau1, c6 or pau3

                db a4 or rep2 or pau1
                db c5 or pau1, e5 or pau1, e5 or pau3
                db e6 or pau1, e6 or pau3, h5 or pau1, h5 or pau3

                db g4 or rep2 or pau1
                db h4 or pau1, g5 or pau1, g5 or pau3
                db g6 or pau1, g6 or pau3, d6 or pau1, d6 or pau3

                db g4 or rep2 or pau1
                db h4 or pau1, g5 or pau1, g5 or pau3
                db g6 or pau1, g6 or pau3, e6 or pau1, e6 or pau3

                db a4 or rep2 or pau1
                db c5 or pau1, e5 or pau1, e5 or pau3, pp or pau3
                db c5 or pau1, e5 or pau1, h5 or pau3, pp or pau3, d5 or pau1

                db h4 or pau1, h4 or pau3
                db a4 or pau1, e5 or pau3
                db d5 or pau1, g4 or pau2

;                db g4 or rep1 or pau1
; replace this last "rep1"-note with two (equal-sounding) notes
                db g4
                db g4 or pau1

msg             db EOM, 'Docking Station',10,'doj&sub'
drumtrk         db 36, 42, 38, 42, 38, 59  ; reversed order to save some bytes !

end start
查看更多
smile是对你的礼貌
3楼-- · 2019-01-25 04:50

Real spaghetti-code requires a multitude of non-local gotos. Sadly this is not possible using most modern languages.

Edit: Some suggest exceptions and longjmp as substitutes for GOTO. But these are far to limited and structured, since they only allow you to return up the callstack. Real GOTO allows you to jump to any line anywhere in the program, which is necessary to create real spaghetti.

查看更多
\"骚年 ilove
4楼-- · 2019-01-25 04:51

Here is the Duff's Device, from Matt's answer to this question:

int n = (count + 7) / 8;
switch (count % 8) {
case 0: do { *to = *from++;
case 7:      *to = *from++;
case 6:      *to = *from++;
case 5:      *to = *from++;
case 4:      *to = *from++;
case 3:      *to = *from++;
case 2:      *to = *from++;
case 1:      *to = *from++;
           } while (--n > 0);
}
查看更多
Fickle 薄情
5楼-- · 2019-01-25 04:56

In simple terms spaghetti code is any code in any programming language in which it is not possible to trace the next post of execution, or at least difficult to determine where the next point goes in response of one action.

查看更多
看我几分像从前
6楼-- · 2019-01-25 04:57

There's also Ravioli Code, which is the opposite. Nice little chunks of functionality, a clean interface neatly wrapped around meaty goodness, all sat in a nice sauce of framework.

查看更多
淡お忘
7楼-- · 2019-01-25 04:58

Don't forget to mention Object-oriented spaghetti. This is when you try to use all the design patterns in the book, even when they don't make sense. This leads to spaghetti code at conceptual level, which is far more detrimental to quality than classical goto-based spaghetti code.

查看更多
登录 后发表回答