In einigen C99-Code muss ich überprüfen, ob die Variable i
im Intervall [0, max]
ist, wobei max
bekanntermaßen positiv ist. Das Problem ist, dass der Typ der Variablen sowohl signiert als auch vorzeichenlos sein darf (indem man typedef
ändert). Wie überprüft man am besten, dass die Variable im Intervall ist?
Der direkte Ansatz wäre:
%Vor% Dies funktioniert gut, wenn wir typedef int my_type;
haben. Aber wenn my_type
unsigniert ist (d. H.% Co_de%), ist typedef unsigned int my_type;
immer wahr und Compiler werden (zu Recht) davor warnen, was ich vermeiden möchte. (Ich möchte diese Warnung nicht ausschalten, da sie nützlich ist, wenn solche Vergleiche tatsächlich unbeabsichtigt sind, und das Ignorieren von Compilerwarnungen ist keine gute Idee.)
Meine aktuelle Idee ist, i >= 0
auf einen vorzeichenlosen Typ zu setzen und einfach die obere Grenze zu prüfen:
Wenn der signierte Typ eine Zweierkomplementdarstellung hat, sollte jeder negative Wert größer als i
sein, wenn er einmal in die unsignierte Version umgewandelt wurde, richtig? Wenn ja, sollte das funktionieren. Ich bin jedoch unsicher, ob dies ein sinnvoller Ansatz ist. Ist es beispielsweise sicher anzunehmen, dass signierte Typen auf allen Plattformen Zweierkomplement verwenden? Gibt es einen besseren Weg, dies zu tun?
Wenn Ihr Compiler das unterstützt, glaube ich, dass die sauberste Lösung darin besteht, den Code unverändert zu lassen, aber die Anweisung #pragma
zu verwenden, um die falsche Warnung lokal zu deaktivieren. Zum Beispiel würde für GCC 4.6.4+ das Folgende Mach den Trick :
Offenbar sollte das exakt gleiche #pragma
s auch für Clang funktionieren , da es die Syntax von GCC imitiert. Andere Compiler können eine ähnliche Syntax haben (zB #pragma warning( disable: ... )
für Visual C / C ++ ), und es sollte möglich sein, Präprozessordirektiven zu verwenden, um die entsprechenden #pragma
s für jeden Compiler auszuwählen.
Der Hauptnachteil dieser Methode ist ästhetisch - sie wirft den Code mit hässlichem #pragma
s aus. Das würde ich jedoch als Vorzug ansehen, wenn Sie Ihren Code absichtlich verdecken (und möglicherweise sogar de-optimieren), nur um eine Compilerwarnung zu vermeiden. Zumindest ist es mit dem #pragma
s für den nächsten Programmierer, der den Code liest, warum er so geschrieben ist, klar.
Um dies übersichtlicher und portabler zu machen, können Sie den C99 _Pragma()
-Operator verwenden um Makros zu definieren, die die Warnungen deaktivieren und wieder aktivieren, z so:
und benutze sie so:
%Vor% Alternativ könnten Sie, wenn Sie Compiler vor C99 unterstützen möchten, ein Paar Header-Dateien ( ohne beliebige Include-Wächter!) erstellen, die so etwas wie warnings_off.h
und warnings_restore.h
enthalten Entsprechende #pragma
für jeden Compiler und dann den Code, für den Sie Warnungen deaktivieren möchten, mit:
Tags und Links c