In C können Sie es mit dem Standardcode vortäuschen.
%Vor%Dies sollte keinen Overhead verursachen und erzeugt Fehler anstelle von Warnungen:
%Vor%Beachten Sie, dass ich keine GNU-Erweiterungen verwende und keine unechten Warnungen generiert werden. Nur Fehler. Beachte auch, dass ich eine Version von GCC verwende, die so alt ist wie Dreck,
%Vor%Dies sollte mit jedem Compiler funktionieren, der die zusammengesetzten Literale von C99 unterstützt.
Clang gibt die folgende Warnung aus, die das Beste ist, was Sie tun können (Obwohl der Benutzer die Warnung auf einen Fehler aktualisieren könnte).
%Vor%Compiler-Ausgabe:
%Vor%Wenn Benutzer Fehler und Warnungen vom Compiler ignorieren, können Sie nicht viel tun, um ihnen zu helfen.
Dies ist die Antwort, die Sie nicht hören möchten. In C kannst du nicht wirklich. Nun, wenn Ihr C-Code in der "Clean C" -Untergruppe von C ++ wäre, könnten Sie mit dem C ++ - Compiler kompilieren, um alle Fehler zu bekommen, die falschen enum / int-Werte zu verwenden, usw.
Leider enum
sind ein Schwachpunkt im Typsystem von C. Variablen eines enum
-Typs sind vom Typ enum
, aber die Konstanten, die Sie mit enum
deklarieren, haben den Typ int
.
Also in Ihrem Beispiel
%Vor% hello
und one
sind zwei Namen für denselben Wert, nämlich 0
und mit demselben Typ int
.
holla
und eins
haben wieder den Wert 0
, haben aber ihre jeweiligen Typen.
Wenn Sie eine "offizielle" Typsicherheit für "echte" Konstanten erzwingen wollen, also Entitäten, die den gewünschten Typ und Wert haben, müssten Sie einige komplexere Konstrukte verwenden:
%Vor% Die Zuweisung im Makro GREETING
stellt sicher, dass das Ergebnis ein "rvalue" ist, so dass es nicht geändert werden kann und vom Compiler nur für seinen Typ und Wert genommen wird.
Wenn Sie auch den gültigen Bereich sicherstellen möchten, gibt es eine Technik, die mit dem kleinen Overhead einer Zeiger-Dereferenzierung zum Erhalten des ganzzahligen Werts - und einer großen Anzahl von Textbausteinen - einhergeht. Es kann immer noch nützlich sein, weil es Ihnen hilft, Bereichsüberprüfungscode zu schreiben, wo es sonst notwendig wäre.
Grüße.h:
%Vor%Grüße.c:
%Vor%Beispiel main.c:
%Vor% Ja, eine Menge zu tippen, aber Sie erhalten volle Art und Reichweite Sicherheit. Keine andere Kompilierungseinheit kann jemals eine struct greetings
instanziieren, so dass Sie vollkommen sicher sind.
Bearbeiten 2015-07-04: Zum Schutz vor NULL gibt es zwei Möglichkeiten. Verwenden Sie entweder NULL als Standardwert ( #define Greetings_hello 0
anstelle des aktuell verwendeten Zeigers). Dies ist sehr praktisch, aber gibt die Sicherheit für Standardaufzählungswerte zurück, NULL kann für jede Aufzählung verwendet werden. Oder deklariere es ungültig und überprüfe es entweder in den Accessor-Methoden, gebe einen Fehler zurück oder verwende etwas wie GCCs __attribute__((nonnull()))
, um es zur Kompilierzeit abzufangen, zB in greetings.h: