Das folgende kurze Codebeispiel enthält einen latenten Defekt, der zu Tage treten kann, wenn der Code für eine andere Plattform kompiliert wird:
char *s;
…
while (isspace(*s)) s++; //
skip over whitespace in the
input
Das Problem besteht darin, dass die Funktion isspace einige nicht sofort ins Auge fallende semantische Eigenschaften besitzt. Es hat beispielsweise den Anschein, als würde die Funktion einen Wert des Typs char als Eingangswert verwenden. Stattdessen aber ist die Funktion so definiert, dass sie einen Parameter des Typs int verarbeitet. Übergibt der Programmierer also einen Wert des Typs char, so wird dieser in einen Wert des Typs int umgewandelt. Dies ist in den meisten Fällen unkritisch. Ist char jedoch ein vorzeichenbehafteter Typ und ist der Wert des Parameters so, dass das höchstwertige Bit 1 lautet, so wird eine Vorzeichenerweiterung durchgeführt, so dass als Resultat irgendein negativer Integer-Wert herauskommt. Handelt es sich beispielsweise um das Zeichen „ß“, dessen hexadezimaler Code 0xdf lautet, so wird an isspace der Wert -33 übergeben. Einige Implementierungen von isspace nutzen den Wert als Index für ein Array. Ein negativer Indexwert verursacht somit einen Zugriff auf Speicher außerhalb der Grenzen des Array. Dies mag im besten Fall nur ein falsches Ergebnis der Funktion zur Folge haben. Ebenso könnte dieser Fehler jedoch einen Programm-absturz auslösen.
Korrekterweise sollte der Code den Parameter also als unsigned char ablegen, um eine Vorzeichenerweiterung zu unterbinden: while (isspace((unsigned char)
*s)) s++;
Ein weiteres Beispiel für einen Code mit Tücken:
struct region r;
memcpy(&r, sizeof(r), 0); //
Zeroise the struct
Hier beabsichtigt der Programmierer, alle Felder auf null zu setzen. Anstatt aber alle Felder nacheinander einzeln explizit mit dem Wert 0 zu belegen, wird die Anweisung memcpy verwendet, um alle Felder auf einmal auf null zu setzen. Dies ist eine durchaus übliche Vorgehensweise, jedoch ist die Schnittstelle zu memcpy als verwirrend berüchtigt. Als zweites Argument soll der Wert (in diesem Fall null) angegeben werden, während es sich beim dritten Argument um die Zahl der Bytes handelt, an die geschrieben werden soll. In dem obigen Beispiel hat der Programmierer den Fehler begangen, die Reihenfolge der Argumente zu verwechseln, was keineswegs selten vorkommt. Es werden also null Bytes geschrieben, so dass die Initialisierung der Variable unterbleibt.
Es kann sein, dass dieser Code auf einer Plattform einwandfrei verarbeitet wird, weil die Werte der entsprechenden Felder zufällig ohnehin null lauten. Auf einer anderen Plattform aber können die Felder irgendwelche beliebigen Werte enthalten, was in einem nicht vorgesehenen Betriebszustand resultiert und das Programm abstürzen lässt.
Leider gibt es noch zahlreiche weitere Situationen, in denen bei der Wiederverwendung von existierendem Code latente Defekte zu Tage treten. Hierzu zählen beispielsweise Pufferüberläufe, Nullzeiger-Dereferenzierungen, Ressourcenlecks, nicht initialisierte Variablen, arithmetische Überläufe, Nebenläufigkeitsfehler und vieles mehr. Die Spanne der möglichen Symptome reicht von echten Abstürzen bis hin zu mysteriösen, schwierig zu diagnostizierenden Verhaltensauffälligkeiten.