hginit - #ifdefs lächerlich


8

Ich habe Joel Spolskys Quecksilber-Einführung gelesen, als es mir auffiel :

"Und jetzt tun sie Folgendes: Jede neue Funktion befindet sich in einem großen # ifdef-Block. Sie können also in einem einzigen Trunk arbeiten, während Kunden den neuen Code erst sehen, wenn er debuggt ist, und ehrlich gesagt ist das lächerlich."

Warum ist das überhaupt so lächerlich , ist das nicht einfach einfacher zu handhaben? Es ist nichts Besonderes, aber es macht den Trick - zumindest wenn Sie bereits mit Subversion "verheiratet" sind.

Was ist der Nachteil? Ich verstehe das Argument irgendwie nicht.


Es ist nicht lächerlich, wenn Sie nur einen oder zwei Schalter haben, aber ich musste mich mit riesigen Ketten bizarr verschachtelter Gruppen von ifdefs auseinandersetzen, und es ist ein Gräuel, zu versuchen, es zu verstehen, und wenn Sie damit umgehen müssten, würden Sie es tun finde es auch lächerlich. Sie denken, dass
verschlungener

Antworten:


20

Ich denke, die Antwort wird im folgenden Satz gegeben:

Stabil und Dev-Code getrennt zu halten, ist genau das, was Sie mit der Quellcode-Kontrolle tun sollen.

Durch die Verwendung von #ifdefBlöcken emulieren Sie die Funktionalität eines Versionsverwaltungssystems mit einem C-Präprozessor. Es ist das falsche Werkzeug für den Job.

Der Nachteil ist, dass Sie wahrscheinlich entweder viel Code duplizieren (denken Sie an ganze Funktionsdefinitionen einmal innerhalb, einmal außerhalb #ifdef) oder unlesbaren Code haben (denken Sie an die #ifdefeinschließenden einzelnen Zeilen innerhalb einer Funktion - möglicherweise wiederholt).

In der ersten Variante werden Fehler am Ende zweimal behoben (was nicht erforderlich wäre, wenn Sie nur Fehlerbehebungen vom stabilen Zweig zum Entwicklungszweig zusammenführen könnten), während in der zweiten Variante das ursprüngliche Ziel der Trennung von stabilen und Entwicklungszweigen nicht wirklich erreicht wurde .


2
+1: In den 80ern hatte ich einen Debugger, der auf fast jedem UNIX-System lief, das man sich vorstellen kann. Vor Version 4 war der Code überflutet #ifdefs. Ich schwöre, es hat meine Augen bluten lassen, als ich es nur ansah. Für Version 4 ging ich mit separaten Dateien zu einer steckbaren Architektur und begann auch mit RCS (oder war es SCCS?). Das Leben wurde massiv besser und neue Funktionen waren viel einfacher zu entwickeln. (Aber Junge, wünschte ich mir jemals, wir hätten damals Git oder HG.)
Peter Rowell

Ich kenne die # ifdef Hölle aus Erfahrung! Ich bin damit einverstanden, dass dies als Ersatz für die Versionskontrolle vermieden werden sollte.
Giorgio

3

#ifdefEs ist lächerlich, Code gepflegt zu haben, der ein Rattennest von s war (obwohl aus verschiedenen Gründen) . Dies erschwert das Lesen und die Wartung von Code erheblich, insbesondere beim Testen unter mehreren Bedingungen.


Ja, ich habe das auch getan und es war schrecklich.
Detly

1

Es wird davon ausgegangen, dass der gesamte neue Code geschrieben werden kann, ohne den vorhandenen Code zu berühren. Oft ist der einzige Weg, dies zu tun, sich selbst viel zu wiederholen. (Eine neue Methode für eine, die zum Beispiel ähnlich, aber nicht genau gleich ist).

Einer der Hauptvorteile von verteiltem VCS besteht darin, dass das Team dazu ermutigt wird, an seinem eigenen Feature-Zweig zu arbeiten und sich keine Sorgen darüber zu machen, dass Ihre Arbeit mit anderen in Konflikt steht. Diese Strategie negiert diesen Vorteil.

Für mich scheint es lächerlich, da sie die Werkzeuge absichtlich missbrauchen. Wenn Sie den Wechsel vornehmen wollen, lohnt es sich sicherlich zu lernen, wie man sie benutzt.


3
Dies ist nicht beschränkt auf DVCS
James

Nein, das wird nicht vorausgesetzt. Selbst bei strategisch platzierten Stellen #ifdefkönnen Sie vorhandenen Code berühren, die alte Version jedoch in einem beibehalten #else.
tdammers

1

#ifdef'ed Code ist nicht lächerlich, aber - traurig und schrecklich. Und es ist (heute) die Diagnose für den Entwickler

Nun, Joel hat in "Subversion Re-Education" The Bad Way (tm) der Argumentation ausgewählt - er hat eine spezielle, entartete Situation mit speziell ausgewählten Benutzern geschaffen und diesen Anwendungsfall als Rechtfertigung für die These "Subversion suxx" verwendet.

Spaghetti-Code suxx mehr, nicht verwaltbarer und unlesbarer Code ist gefährlicher, als einige Zeit mit der Umerziehung von "Right Merge" in Subversion zu verbringen - "Merge oft, Idioten !!!" Verzweigung und bidirektionale Zusammenführung waren in Subversion <1.5 möglich und verwendbar. Jetzt (nach Einführung von mergeinfo) wird die Zusammenführung noch einfacher und komfortabler . Ein geringer Aufwand für die Überwachung "interessanter" Bäume und Synchronisierungen (oft !!!) ist ein fairer Preis für Entwickler, die im Gegenzug kompakten, sauberen und debuggbaren Code erhalten.


1

Was er beschreibt, ist eigentlich ein FeatureToggle , und es kann gute Gründe geben, dies anstelle von Feature-Zweigen zu verwenden. Das Problem ist mit der Verwendung #ifdef. Ohne ein sehr gutes Management können sie leicht zu einem großen Durcheinander werden, das rund um die Codebasis verstreut ist.

Folgendes berücksichtigen:

  1. Wann entfernen Sie eine #ifdef? - Sind Sie sicher, dass keine Builds mehr vorhanden sind, die diese Funktion noch ausschließen? Auch nicht für diesen einen (gut bezahlten) Kunden, für den Sie einige spezielle Builds erstellen?
  2. Wer ist für das Entfernen der verantwortlich #ifdef? - Der Entwickler, der das Feature erstellt hat? Sind Sie sicher, dass er sich 4 Wochen später daran erinnern wird, um zu überprüfen, ob der Switch in einem Build nicht ausgeschlossen ist und sicher entfernt werden kann? Wird er zuversichtlich sein, dass es sicher ist, das zu entfernen #ifdef? Was ist mit dieser anderen extrem dringenden Aufgabe, hat das nicht Vorrang vor dem Entfernen eines dürren #ifdef?

Meine Erfahrung sagt, dass solche #ifdefs für immer herumliegen werden, Müll.


1

Aus Erfahrung (bei einem großen Projekt in einer Codebasis mit mehr als 600.000 Zeilen, die 3 Jahre lang mit #ifdefs aus Releases herausgehalten wurde ) wären meine Argumente gegen deren Verwendung:

  • Sie verringern die Lesbarkeit des Codes - insbesondere, da einige IDEs darauf bestehen, sie am Anfang der Zeile zu platzieren und die Einrückungsstufe zu ignorieren.
  • Sie erhöhen die Komplexität, sowohl für die Entwickler, die an der getrennten Funktion arbeiten, als auch für die Entwickler, die versuchen, sie zu umgehen.
  • Diese zusätzliche Komplexität verlangsamt die Produktivität - in unserem Fall bin ich überzeugt, dass das Projekt um mehrere Monate verlängert wurde.
  • Das Entfernen nach der Veröffentlichung der Funktion ist keine Null-Kosten-Aufgabe. In unserem Fall war es eine einwöchige Aufgabe, alle #ifdefs durchzugehen und alle s zu entfernen und die Konflikte mit dem in #elseifs hinzugefügten Code zu lösen .

Alles in allem war es ein herrlicher Tag, als wir zu Mercurial migrierten - wir haben immer noch eine riesige, übermäßig komplexe Codebasis, aber zumindest können wir jetzt effizient verzweigen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.