Frage

Auf den Fersen ein spezifisches Problem, Ich würde gerne verstehen, ob es sich um eine richtige Lösung, eine Problemumgehung/Hack oder einfach falsch handelt.

Insbesondere habe ich Code neu geschrieben:

T x = ...;
if (*reinterpret_cast <int*> (&x) == 0)
  ...

Wie:

T x = ...;
if (*reinterpret_cast <volatile int*> (&x) == 0)
  ...

mit einer volatile Qualifikation zum Zeiger.

Nehmen wir einfach an, dass das behandeln T wie int in meiner Situation macht Sinn. Zugriff dies über a volatile Referenzlöser Zeiger -Aliasing -Problem?

Als Referenz aus der Spezifikation:

Hinweis: Volatile ist ein Hinweis auf die Implementierung, um eine aggressive Optimierung des Objekts zu vermeiden, da der Wert des Objekts durch eine durch eine Implementierung nicht nachweisbare Mittel geändert werden kann. Siehe 1.9 für detaillierte Semantik. Im Allgemeinen sollen die Semantik von flüchtigem in C ++ gleich sein wie in C. - Endnote

BEARBEITEN:

Der obige Code hat mein Problem zumindest bei GCC 4.5 gelöst.

War es hilfreich?

Lösung

Völlig kann Ihnen nicht helfen, ein undefiniertes Verhalten hier zu vermeiden. Also, wenn es mit GCC für Sie funktioniert, ist es Glück.

Nehmen wir an, T ist ein Pod. Dann ist der richtige Weg, dies zu tun

T x = …;
int i;
memcpy(&i,&x,sizeof i);
if (i==0)
  …

Dort! Kein striktes Aliasing -Problem und kein Problem mit Gedächtnisausrichtungen. GCC behandelt sogar Memcpy als intrinsische Funktion (in diesem Fall wird kein Funktionsaufruf eingefügt).

Andere Tipps

Völlig kann Ihnen nicht helfen, ein undefiniertes Verhalten hier zu vermeiden.

Nun, alles in Bezug auf volatile ist im Standard etwas unklar. Ich stimmte hauptsächlich mit Ihrer Antwort zu, aber jetzt möchte ich etwas nicht zustimmen.

Um zu verstehen was volatile Mittel, der Standard ist für die meisten Menschen nicht klar, insbesondere einige Compiler -Autoren. Es ist besser zu denken:beim Benutzen volatile (und nur wenn) C/C ++ ist ziemlich hoch auf hoher Stufe Montage.

Beim Schreiben an a volatile LVALUE, der Compiler stellt ein Geschäft oder mehrere Speicher aus, wenn man nicht ausreicht (volatile impliziert nicht atomar).

Beim Schreiben an a volatile LVALUE, der Compiler stellt eine Last oder mehrere Last aus, wenn einer nicht ausreicht.

Wenn es keine explizite Last oder Speicher gibt, gibt der Compiler nur Anweisungen aus, die eine Last oder Speicher implizieren.

Sellibitze gab die beste Lösung: verwenden memcpy für Bit -Neuinterpretationen.

Aber wenn alle Zugriffe auf eine Speicherregion mit erledigt sind volatile lvalues, Es ist vollkommen klar, dass die strengen Aliasing -Regeln nicht gelten. Dies ist die Antwort auf Ihre Frage.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top