hginit - #ifdefs ridicolo

8

Stavo leggendo l'introduzione mercuriale di Joel Spolsky quando mi ha colpito:

"And now what they do is this: each new feature is in a big #ifdef block. So they can work in one single trunk, while customers never see the new code until it’s debugged, and frankly, that’s ridiculous."

Perché è così ridicolo comunque, non è questo, se non altro, semplicemente più semplice da gestire? Non è niente di eccezionale ma fa il trucco - almeno se sei già "sposato" con la sovversione.

Qual è il lato negativo? Non riesco a ottenere l'argomento.

    
posta panny 23.01.2013 - 20:45
fonte

6 risposte

21

Penso che la risposta sia data nella frase successiva:

Keeping stable and dev code separate is precisely what source code control is supposed to let you do.

Usando i blocchi #ifdef , si sta emulando la funzionalità di un sistema di controllo del codice sorgente con un preprocessore C. È lo strumento sbagliato per il lavoro.

Il rovescio della medaglia è che probabilmente finirai per duplicare un sacco di codice (pensa a definizioni di una funzione intera una volta dentro, una volta all'esterno di #ifdef ) o codice illeggibile (pensa a #ifdef che racchiude le singole linee all'interno di una funzione - eventualmente ripetutamente).

Nella prima variante finisci per correggere i bug due volte (cosa che non sarebbe necessaria se tu potessi semplicemente unire correzioni di bug dal ramo stabile al ramo dev), mentre nel secondo l'obiettivo originale di separare i rami stable e dev non sono stati realmente raggiunti.

    
risposta data 23.01.2013 - 21:03
fonte
3

Avendo mantenuto il codice che era il nido di un ratto di #ifdef s (anche se per ragioni diverse), è ridicolo; rende il codice molto più difficile da leggere e molto più difficile da mantenere, specialmente quando si testano condizioni multiple.

    
risposta data 23.01.2013 - 23:34
fonte
1

Presuppone che tutto il nuovo codice possa essere scritto senza toccare il codice esistente. Spesso l'unico modo per farlo è ripeterti molto. (un nuovo metodo per uno che è simile ma non esattamente lo stesso ad esempio).

Uno dei principali vantaggi del VCS distribuito è che incoraggia il team a lavorare sul proprio ramo delle funzionalità e non si preoccupa del fatto che il tuo lavoro sia in conflitto con gli altri. Questa strategia nega questo vantaggio.

Per me sembra ridicolo, dal momento che sembrano deliberatamente abusare degli strumenti. Se stai andando a fare lo switch sicuramente vale la pena imparare a usarli.

    
risposta data 23.01.2013 - 21:08
fonte
1

#ifdef 'ed il codice non è ridicolo, ma - triste e terribile. Ed è (oggi) la diagnosi per lo sviluppatore

Bene, Joel ha selezionato in "Subversion Re-education" The Bad Way (tm) di argomentazione - ha creato situazioni speciali degenerate con utenti appositamente selezionati e usa questo caso d'uso come giustificazione per la tesi "Subversion suxx"

Codice di spaghetti suxx di più, codice ingovernabile e illeggibile è più pericoloso, piuttosto che dedicare un po 'di tempo alla rieducazione di "Right Merge" in Subversion - "Unisci spesso, deficienti !!!" Branching e unione bidirezionale era possibile e utilizzabile in Subversion < 1.5, now (dopo aver introdotto mergeinfo) si uniscono diventano anche più facili e più constrongvole . Il piccolo overhead di monitoraggio di alberi "interessanti" e sync-merges (spesso !!!) è un prezzo equo per gli sviluppatori, che ottengono in cambio un codice compatto, pulito e debuggabile.

    
risposta data 24.01.2013 - 07:16
fonte
1

Quello che sta descrivendo è in realtà un FeatureToggle , e ci possono essere buoni motivi per utilizzare quello anziché i rami delle funzionalità. Il problema è con l'utilizzo di #ifdef . Senza una buona gestione possono facilmente diventare un gran caos disseminato tutto intorno al code-base.

Considera quanto segue:

  1. Quando rimuovi un #ifdef ? - Sei sicuro che non ci siano ancora build che escludano ancora quella caratteristica? Inoltre, non per quel cliente (che paga bene) per chi crea qualche build speciale?
  2. Chi è responsabile della rimozione di #ifdef ? - Lo sviluppatore che ha realizzato la funzione? Sei sicuro che ricorderà 4 settimane dopo la linea, per verificare che l'interruttore non sia escluso in qualsiasi build e possa essere rimosso in sicurezza? Sarà sicuro che è sicuro rimuovere il #ifdef ? Che dire di questo altro compito estremamente urgente, non ha la priorità sulla rimozione di un misero #ifdef ?

La mia esperienza dice che tali% di#ifdef s saranno messi per sempre, sporchi.

    
risposta data 24.01.2013 - 07:38
fonte
1

Dall'esperienza (su un grande progetto in una base di codice di oltre 600.000 righe, che è stato tenuto fuori dalle release per 3 anni usando #ifdef s) i miei argomenti contro il loro utilizzo sarebbero:

  • Riducono la leggibilità del codice, in particolare perché alcuni IDE insistono nel posizionarli all'inizio della riga ignorando il livello di indentazione.
  • Aggiungono complessità, sia agli sviluppatori che lavorano sulla funzione segregata sia agli sviluppatori che cercano di aggirarli.
  • Questa ulteriore complessità rallenta la produttività, nel nostro caso sono convinto che abbia aggiunto diversi mesi al progetto.
  • Rimuoverli una volta che la funzione è stata rilasciata non è un compito a costo zero - nel nostro caso è stato un compito lungo una settimana che qualcuno doveva passare e rimuovere tutti #ifdef s e risolvere i conflitti con il codice che era stato aggiunto in #elseif s.

Tutto sommato è stato un giorno glorioso quando siamo migrati su Mercurial - abbiamo ancora una base di codice enorme, eccessivamente complessa, ma almeno ora possiamo diramarti efficientemente.

    
risposta data 24.01.2013 - 14:09
fonte

Leggi altre domande sui tag