Zum Inhalt springen
L

Wikipedia · einfach zusammengefasst · Stand

Toter Code

Toter Code (englisch dead code) ist in der Programmierung ein Begriff für Teile eines Computerprogramms, „die an keiner Stelle im Programm verwendet werden“.

Inhalt5 Abschnitte
  1. 1. Begriff und Abgrenzung
  2. 2. Bedeutung und Risiken
  3. 3. Typische Formen am Beispiel
  4. 4. Entstehung und Erkennung
  5. 5. Entfernung und Grenzen

Begriff und Abgrenzung

Toter Code (englisch dead code) bezeichnet in der Programmierung Teile eines Computerprogramms, „die an keiner Stelle im Programm verwendet werden“. Dazu können Anweisungen oder Befehle ebenso gehören wie nicht verwendete Datendeklarationen. Im erweiterten Sinn ist toter Code eine Sonderform redundanten, also überflüssigen Codes.

Davon abzugrenzen ist unerreichbarer Code: Dieser kann durch keinen möglichen Kontrollfluss erreicht werden und wird deshalb nicht ausgeführt. Umgangssprachlich wird auch unerreichbarer Code oft als toter Code bezeichnet. Außerdem gibt es unnötigen Code, etwa eine Bedingung, die immer wahr ist. Er gehört nicht zwingend zu den genannten Kategorien, wird aber ebenfalls häufig als toter Code bezeichnet.

Bedeutung und Risiken

Alle Formen toten Codes gelten als unerwünscht und als Mangel der Softwarequalität. Häufig weist er auf einen Programmfehler hin; ihn zu entdecken ist deshalb ein Ziel beim Softwaretest.

Toter Code kann aber auch absichtlich vorhanden sein, etwa um einen vorläufigen oder früheren Quelltextteil zu erhalten. Seine Ergebnisse werden zwar nicht verwendet, dennoch kann der Code Ausnahmebehandlungen auslösen oder globale Status beeinflussen. Wird er entfernt, kann sich daher die Programmausgabe verändern und es können unbeabsichtigte Fehler entstehen. Ob solcher Code dann noch als toter Code gilt, ist umstritten.

Typische Formen am Beispiel

In der Funktion foo(int x) ist int y = 100 / x; toter Code, weil y nie verwendet wird. Bei x gleich Null löst die Division jedoch eine Ausnahme aus. Das Entfernen ändert also die Funktionalität; laut Beispiel sollte das Auslösen der Ausnahme aber ohnehin nie Teil der Funktionalität sein und ist deshalb fehlerhaft.

int z = x * x; und das spätere return x * x; sind redundant, weil x dazwischen nicht verändert wird und beide Ausdrücke immer dasselbe Ergebnis haben. Stattdessen wäre return z; angebracht. Die Bedingung if (z >= 0) ist unnötig, da ein Quadrat stets mindestens 0 ist. Weil die Bedingung immer wahr ist und im Block die Methode verlassen wird, ist das folgende return -1; unerreichbar.

Eine redundanzfreie Fassung der Funktion lautet: int foo (int x) { return x*x; }.

Entstehung und Erkennung

Toter Code kann durch Programmierfehler, unvollständige Tests oder einen bei einer Fehlerkorrektur neu eingeführten Fehler entstehen. Weitere Ursachen sind Code, der wegen seiner Vermischung mit funktionalem Code nicht entfernt wurde, vergessene Löschungen, veränderte Eingabedaten oder absichtlich unerreichbar gemachter Code, der später wiederverwendet werden soll. Auch Debugging-Konstrukte und Reste von Entwicklungscode zählen dazu. In den letzten fünf dieser Fälle ist der unerreichbare Code eine Altlast: Er war früher sinnvoll, wird aber nicht mehr benötigt.

Ein typisches absichtliches Beispiel ist eine Kontrollausgabe mit #define DEBUG 0. Während der Entwicklung kann DEBUG auf einen von Null verschiedenen Wert gesetzt werden, damit etwa der Wert von a ausgegeben wird. Bei DEBUG gleich 0 erkennt und entfernt der Präprozessor den nun toten Abschnitt.

Das Auffinden ist eine Form der statischen Codeanalyse. Sie untersucht die Ablaufsteuerung, um Code unabhängig von Variablen und anderen Laufzeitbedingungen zu erkennen. Werkzeuge finden viele tote und unerreichbare Teile; in Java sind einige Formen unerreichbaren Codes verboten und führen zu Kompilierungsfehlern. In großen Projekten können ganze Module schwer erkennbar sein, etwa wenn Testgerüste Code noch als „lebendig“ erscheinen lassen oder Vertragspflichten seine Auslieferung verlangen. Profiling liefert nur eine Heuristik für potenziell unerreichbaren Code, keinen Beweis; verdächtige Stellen müssen danach mit stärkerer Analyse oder von Hand geprüft werden.

Entfernung und Grenzen

Seit Mitte der 1990er Jahre erkennen und entfernen Compiler und Linker unbenutzte Abschnitte mit dead code elimination. Seit Mitte der 2010er Jahre zeigen auch IDEs unbenutzten Code beim Editieren an; Debugger können im aktuellen Durchlauf nicht mehr erreichbaren Code abgedunkelt darstellen.

Die Entfernung erfolgt meist durch Löschen der betreffenden Stellen, verlangt aber Vorsicht wegen möglicher Seiteneffekte, die nicht unmittelbar erkennbar sind. Compiler arbeiten deshalb konservativ: Bei Mehrdeutigkeit über das Programmverhalten wird Code nicht entfernt. Toter Code kann durch Variablenanalyse, unerreichbarer Code durch Datenflusskontrolle erkannt werden. Compilertransformationen wie common subexpression elimination können Code selbst unerreichbar machen.

Constant folding und einfache Flussanalyse zeigen beispielsweise bei int i = 2 + 1; if (i == 4) foo();, dass foo() unerreichbar ist. Wie viel Code gefunden wird, hängt stark von der Ausgereiftheit der Analyse ab; einer vollständigen Analyse zur Kompilierungszeit setzen theoretische Grenzen der Entscheidbarkeitsproblematik Grenzen. Im November 2010 wurde Microsoft kritisiert, weil eine spezielle dead code elimination den Internet Explorer in einem bekannten JavaScript-Benchmark besonders schnell erscheinen ließ, während die Ergebnisse in anderen Benchmarks eher im Mittelfeld lagen.

Weiterlesen

Programmierung Beim Programmieren sind wesentliche Aspekte zur Softwarequalität zu berücksichtigen und durch die Gestaltung des Quellcodes umzusetzen. Siehe dazu als Beispiele … Anweisung (Programmierung) Anweisungen sind üblicherweise Zuweisungen, Kontrollanweisungen (wie Sprünge, Schleifen und bedingte Anweisungen) und Prozeduraufrufe. Abhängig von der … Deklaration (Programmierung) In der Informatik und Programmierung ist eine Deklaration die Festlegung von Dimension, Bezeichner, Datentyp und weiteren Aspekten einer Variable oder eines … Kontrollfluss Der Kontrollfluss oder Programmablauf bezeichnet in der Informatik die zeitliche Abfolge der einzelnen Befehle eines Computerprogramms. Softwarequalität „Unter Softwarequalität versteht man die Gesamtheit der Merkmale und Merkmalswerte eines Softwareprodukts, die sich auf dessen Eignung beziehen, … Softwaretest Ein Softwaretest prüft und bewertet Software auf Erfüllung der für ihren Einsatz definierten Anforderungen und misst ihre Qualität. Null Die Zahl Null ist die Anzahl der Elemente in einer leeren Ansammlung von Objekten, mathematisch gesprochen die Kardinalität der leeren Menge. Englische Sprache Die englische Sprache (Eigenbezeichnung: [ˈɪŋɡlɪʃ]) ist eine ursprünglich in England beheimatete germanische Sprache, die zum westgermanischen Zweig gehört. Statische Code-Analyse Statische Code-Analyse oder kurz statische Analyse ist ein statisches Software-Testverfahren, das zur Übersetzungszeit durchgeführt wird. Java (Programmiersprache) Java ist eine objektorientierte Programmiersprache und eine eingetragene Marke des Unternehmens Sun Microsystems, welches 2010 von Oracle übernommen wurde. Compiler Ein Übersetzer zur Übertragung von Assembler-Quellprogrammen in Maschinensprache wird als Assembler oder Assemblierer bezeichnet. Geschichte. Bearbeiten. Entscheidbarkeit In der theoretischen Informatik heißt eine Eigenschaft auf einer Menge ... (Halteproblem) oder die Funktionsgleichheit zweier Programme (Äquivalenzproblem).