Frage zum Typ punning: Warum bricht dieser Code strenge Aliasing-Regeln:
%Vor%und das ist nicht:
%Vor% Erstellen von gcc -fstrict-aliasing
.
Danke!
Beide verstoßen gegen die strenge Aliasing-Regel , ich zitiere meine Antwort hier , die sagt ( Betonung meiner Zukunft ):
code verletzt die strengen Aliasing-Regeln , die illegal machen Zugriff auf ein Objekt über einen Zeiger eines anderen Typs , obwohl der Zugriff über ein char * zulässig ist. Der Compiler darf annehmen, dass Zeiger unterschiedlicher Typen nicht auf den gleichen Speicher zeigen und entsprechend optimieren.
gcc
ist ein wenig detaillierter in der Dokumentation von -Wstrict-aliasing=n
hier sagt:
Diese Option ist nur aktiv, wenn -fstrict-aliasing aktiv ist. Es warnt vor Code, der die strengen Aliasregeln, die der Compiler zur Optimierung verwendet, durchbrechen könnte. Höhere Ebenen entsprechen einer höheren Genauigkeit (weniger Fehlalarme) . Höhere Ebenen entsprechen auch mehr Aufwand, ähnlich wie -O funktioniert. -Werstrict-Aliasing entspricht -Wstrict-Aliasing = 3.
und beschreibt jede Ebene wie folgt:
Stufe 1: Am aggressivsten, schnell, am wenigsten genau. Vielleicht nützlich, wenn höhere Level warnen nicht, aber - das Aliasing von Frames - bricht immer noch den Code, da es sehr wenige falsche Negative hat. Es hat jedoch viele falsche Positives. Warnt für alle Zeigerkonvertierungen zwischen möglicherweise inkompatible Typen, auch wenn sie nie dereferenziert wurden. Läuft im vorderen Ende nur.
Level 2: Aggressiv, schnell, nicht zu präzise. Kann noch viele falsche haben Positives (nicht so viele wie Level 1) und wenige falsche Negative (aber möglicherweise mehr als Stufe 1). Im Gegensatz zu Level 1 warnt es nur wann Eine Adresse ist vergeben. Warnt vor unvollständigen Typen. Läuft vorne nur beenden.
Level 3 (Standard für -Werstrict-Aliasing): Sollte nur sehr wenige falsche Werte enthalten Positive und wenige falsche Negative. Etwas langsamer als Level 1 oder 2 wenn die Optimierung aktiviert ist. Kümmert sich um das gemeinsame Wortspiel + Dereferenzierung Muster im Frontend:
*(int*)&some_float
. Wenn Optimierung ist aktiviert, läuft es auch im Backend, wo es sich um mehrere handelt Anweisungsfälle, die flußempfindliche Punkte verwenden. Warnt nur wenn der konvertierte Zeiger dereferenziert wird. Warnt nicht vor unvollständige Typen.
Es ist also nicht garantiert, dass alle Instanzen abgefangen werden und verschiedene Ebenen unterschiedliche Genauigkeitsgrade haben.
In der Regel kann der Effekt, den Sie suchen, mit type punning durch eine Union erreicht werden, die ich in meiner verknüpften Antwort oben abdecke und gcc unterstützt explizit .
Tags und Links c gcc strict-aliasing