Der Hinweis hier ist, dass die Codebasis sehr alt ist.
Dieser Trick existiert wahrscheinlich, weil der Code einmal auf einen Compiler mit einem sehr alten Präprozessor portiert wurde, der undefinierte Makros in Präprozessorbedingungen nicht als 0 behandelt #if.
Das heißt, ab 1989 ANSI C wurde standardisiert, dass, wenn wir haben:
#if foo + bar - xyzzy
die Richtlinie unterliegt Makro - Ersatz, dass dann , wenn er foo, baroder xyzzyMakros sind, sie ersetzt werden. Dann werden alle verbleibenden Bezeichner, die nicht ersetzt wurden, durch ersetzt 0. Wenn fooalso definiert ist als 42, aber barund xyzzyüberhaupt nicht definiert sind, erhalten wir:
und nicht zum Beispiel schlechte Syntax:
oder ein anderes Verhalten, wie die Diagnose, dass es barnicht definiert wurde.
Auf einem Präprozessor, bei dem undefinierte Makros als Leerzeichen behandelt werden, wird #if SOMETHING_SUPPORTEDauf just erweitert #if, was dann fehlerhaft ist.
Nur so IDENT+0macht dieser Trick wirklich Sinn. Sie würden dies einfach nie tun wollen, wenn Sie sich darauf verlassen können, dass die Vorverarbeitung ISO C-konform ist.
Der Grund dafür ist, dass, wenn SOMETHING_SUPPORTEDerwartet wird, dass sie numerische Werte haben, es fälschlicherweise verstreut ist, sie einfach als Leerzeichen zu definieren. Idealerweise möchten Sie erkennen, wann dies geschehen ist, und die Kompilierung mit einer Diagnose beenden.
Zweitens, wenn Sie tun , eine solche Streu-brained Nutzung unterstützen Sie mit ziemlicher Sicherheit ein explizit definiert, aber leere Symbol zu verhalten , als ob es den Wert 1 hatte, nicht den Wert 0. Ansonsten sind Sie eine Falle zu schaffen. Jemand könnte dies in der Compiler-Befehlszeile tun:
-DSOMETHING_SUPPORTED=$SHELL_VAR
oder im Code:
#define SOMETHING_SUPPORTED
Niemand wird ein oder für ein Symbol hinzufügen , um die von ihm gesteuerte Funktion auszuschalten ! Der Programmierer, der ein ohne das einfügt, wird vom Verhalten von überrascht sein#define-D#define SOMETHING_SUPPORTED1
Dadurch wird das Material übersprungen, das aktiviert werden sollte.
Aus diesem Grund vermute ich, dass nur wenige C-Programmierer, die dies lesen, jemals eine solche Verwendung gesehen haben, und ich vermute, dass dies nur eine Problemumgehung für das Verhalten des Präprozessors ist, dessen beabsichtigter Effekt darin besteht, den Block zu überspringen, wenn er SOMETHING_SUPPORTEDfehlt. Die Tatsache, dass es sich um eine "Programmierfalle" handelt, ist nur ein Nebeneffekt der Problemumgehung.
Um ein solches Präprozessorproblem zu umgehen, ohne eine Programmierfalle zu erstellen, muss irgendwo in der Übersetzungseinheit Folgendes vorhanden sein:
#ifndef SOMETHING_SUPPORTED
#define SOMETHING_SUPPORTED 0
#endif
und dann woanders einfach benutzen #if SOMETHING_SUPPORTED. Vielleicht kam dieser Ansatz dem ursprünglichen Programmierer nicht in den Sinn, oder vielleicht hielt dieser Programmierer diesen +0Trick für ordentlich und legte Wert auf seine Selbstbeherrschung.