Quelle: Nicht initialisierter Müll auf ia64 kann tödlich sein
Auf der ia64 ist jedes 64-Bit-Register tatsächlich 65 Bits. Das Extra-Bit heißt "NaT", was für "kein Ding" steht. Das Bit wird gesetzt, wenn Das Register enthält keinen gültigen Wert. Betrachten Sie es als das ganzzahlige Version des Fließkomma NaN.
Das NaT-Bit wird am häufigsten aus spekulativer Ausführung gesetzt. Dort ist eine spezielle Form des Ladebefehls auf der ia64, die versucht Laden Sie den Wert aus dem Speicher, aber wenn der Ladevorgang fehlschlägt (weil der Speicher wird ausgelagert oder die Adresse ist ungültig), dann statt a Seitenfehler, alles, was passiert, ist, dass NaT Bit gesetzt wird, und die Ausführung fährt fort.
Alle mathematischen Operationen an NaT erzeugen einfach wieder NaT.
Der Quellartikel fuhr fort, zu erklären, wie ein Register beim spekulativen Laden eine NaT-Darstellung haben könnte und macht folgende Bemerkung:
Denn Sie sehen, wenn Sie ein Register haben, dessen Wert NaT ist und Sie so sehr atme auf ihm den falschen Weg (zum Beispiel versuche, seinen Wert zu speichern Speicher) wird der Prozessor eine STATUS_REG_NAT_CONSUMPTION auslösen Ausnahme.
es scheint von anderen Stack-Überlauf Antworten auf Trap-Darstellungen, die, "Jeder Typ (außer unsigniertes Zeichen) kann Trap-Repräsentationen haben".
Dieser Link sagt das
Das einzige, was der Standard garantiert, ist der Zugriff auf nicht initialisierte Daten sind, dass der unsigned Char-Typ keine Trap-Repräsentationen hat und Dieses Padding hat keine Trap-Repräsentationen.
Wenn ein solches Register (ein Register mit NaT-Bit Set) zum Speichern eines nicht initialisierten, unsignierten Zeichens (ähnlich dem Codefragment aus dem unten stehenden Fehlerbericht) zugewiesen wird, wie wird dies gemäß ISO C11 gehandhabt?
Weist der folgende Fehlerbericht auf das gleiche Problem hin und ist es in ISO C11 behoben?
Wenn nicht, wie dieser spezielle Fall behandelt wird?
Wenn der Wert l ein Objekt mit automatischer Speicherdauer angibt, das hätte mit register storage class deklariert werden können (hatte nie seine Adresse genommen), und dieses Objekt ist nicht initialisiert (nicht mit einem deklariert Initialisierer, und keine Zuordnung wurde vor dem verwenden), das Verhalten ist nicht definiert
behandelt der obige Zusatz am Ende des Fehlerberichts im Abschnitt "Änderung für C1X" diesen Fall?
%Vor%Die folgende Funktion hat unter C90 undefiniertes Verhalten, erscheint aber streng nach C99 zu entsprechen
Als erstes, wenn Sie es nicht selbst gesehen haben, können Sie den endgültigen Entwurf des C11-Standards von hier ( siehe auch ).
Der Text aus dem DR wurde tatsächlich zu Abschnitt 6.3.2.1 p2 hinzugefügt, wodurch der Code gemäß C11 undefiniert wird.
Die Abschnitte im Standard über Trap-Repräsentationen schließen weiterhin die Möglichkeit aus, dass unsigned char
eine Trap-Repräsentation haben kann - aber das spielt keine Rolle. Hier ist anzumerken, dass, wie in der Erwähnung des Frühjahrs 2008 in der DR erwähnt, aus einer Standardperspektive eigentlich gar keine Trap - Repräsentationen selbst involviert sein müssen (sie sind nur der wahrscheinliche Mechanismus, durch den die UB eine Problem für dich auf dem Metall). Das Problem betrifft wirklich nicht initialisierte automatische Werte. Der geänderte Absatz löst dies, indem klargestellt wird, dass unsigned char
nicht von einem allgemeinen Typ von UB ausgenommen werden sollte, einfach weil eins seiner typspezifischen Eigenschaften (nicht durch Hinzufügen von mehr Komplexität für diese Eigenschaft).
Sie können sich vorstellen, dass genau wie NaT-Bits ein Implementierungsdetail von Ganzzahlen in IA64 sind, das Fehlen einer Trap-Repräsentation ein "Implementierungsdetail" eines bestimmten Typs innerhalb der allgemeinen Familie von C-Typen ist. Der tatsächliche Typ der Variablen ist sekundär zu der allgemeineren Regel, dass Sie nicht sicher sein sollten, auf eine nicht initialisierte Variable zuzugreifen; Der Zusatz verdeutlicht diesen Vorrang.
Tags und Links c