2010-06-05 8 views
8

Auf den Fersen von a specific problem, eine Selbst-Antwort und Kommentare dazu, würde ich gerne verstehen, wenn es eine richtige Lösung, Workaround/Hack oder einfach nur falsch ist.Strict-Pointer-Aliasing: Ist der Zugriff über einen 'flüchtigen' Zeiger/Verweis auf eine Lösung?

Insbesondere neu geschrieben I-Code:

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

As:

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

mit einem volatile Qualifier auf den Zeiger.

Nehmen wir einfach an, dass die Behandlung T als int in meiner Situation sinnvoll ist. Wird durch das Zugreifen über eine volatile Referenz das Pointer-Aliasing-Problem gelöst?

Für eine Referenz, von der Spezifikation:

[Anmerkung: volatile ist ein Hinweis auf die Umsetzung Einbeziehung des Objekts aggressive Optimierung zu vermeiden, weil der Wert des Objekts könnte mittels nicht nachweisbar durch ein geändert werden Implementierung. Siehe 1.9 für detaillierte Semantik. In der Regel wird die Semantik von flüchtigen soll das gleiche in C sein ++, wie sie in C sind - Endnote]

EDIT:

Der obige Code hat mein Problem zumindest auf GCC lösen 4.5 .

+0

Diese Frage ist ** nicht ** eindeutig C++ spezifisch. Die C++ - artigen Umwandlungen können in C einfach umgeschrieben werden. – curiousguy

+0

@curiousguy C und C++ haben jedoch unterschiedliche Sprachregeln –

+0

@MattMcNabb Wie sind die verschiedenen WRTs "flüchtig"? – curiousguy

Antwort

15

Volatile kann Ihnen nicht helfen, undefiniertes Verhalten hier zu vermeiden. Also, wenn es für Sie mit GCC 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 Speicherausrichtungsproblem. GCC behandelt sogar memcpy als eine intrinsische Funktion (in diesem Fall wird kein Funktionsaufruf eingefügt).

+1

"Volatile kann Ihnen nicht helfen, undefiniertes Verhalten hier zu vermeiden" - warum? Haben Sie eine Quelle für diese Aussage? – doublep

+5

C++ - Standard, Abschnitt 3.10 Absatz 15 ist der Ort, den Sie in Bezug auf strenge Aliasing betrachten müssen. Es wird keine Ausnahme erwähnt, die Volatilität beinhaltet. – sellibitze

+0

Es gibt Fälle, in denen das Verhalten nicht undefiniert ist. Zum Beispiel: struct A {int a; }; int main() {X x; * reinterpret_cast (& x) = 10; } 'ist gut und perfekt definiert nach' 9.2/17'. Das Objekt hat den Typ "int", und der Wert lvalue ist ebenfalls vom Typ "volatile int", daher funktioniert das Aliasing gut. –

-3

Flüchtige kann nicht helfen, hier undefiniertes Verhalten zu vermeiden.

Nun, alles in Bezug auf volatile ist etwas unklar in der Norm. Ich stimme Ihrer Antwort größtenteils zu, aber jetzt möchte ich ein wenig widersprechen.

Um zu verstehen, was volatile bedeutet, ist der Standard für die meisten Menschen nicht klar, insbesondere einige Compiler-Autoren. Es ist besser zu denken: bei Verwendung volatile (und nur wenn), C/C++ ist ziemlich viel hoher Ebene Assembly.

Beim Schreiben in einen volatile lvalue gibt der Compiler einen STORE aus, oder mehrere STORE, wenn einer nicht ausreicht (volatile bedeutet nicht atomar).

Beim Schreiben in einen volatile L-Wert gibt der Compiler eine LOAD- oder mehrere LOAD-Befehle aus, wenn eine nicht ausreicht.

Natürlich, wo es keine explizite LOAD oder STORE gibt, wird der Compiler nur Anweisungen ausgeben, die eine LOAD oder STORE bedeuten.

sellibitze gab die beste Lösung: Verwendung memcpy für Bit-Neuinterpretationen.

Aber wenn alle auf einen Speicherbereich greift mit volatile lvalues ​​fertig sind, es ist vollkommen klar, dass die strengen Aliasing Regeln nicht gelten. Dies ist die Antwort auf Ihre Frage.

+0

Warum der Downvote? – curiousguy

+6

-1: Erstens, das ist kein Forum; Wir antworten nicht auf Antworten in Antworten. Wenn Sie denken, dass Sie eine bessere Antwort haben, dann schreiben Sie eine Antwort, die die Frage adressiert. Zweitens und noch wichtiger: "Alles, was mit Volatilität zu tun hat, ist im Standard etwas unklar." Nein, ist es nicht. Der Standard ist * sehr * klar darüber, wie flüchtig und nichtflüchtig die abstrakte Maschine ist. –

+1

@NicolBolas "_Zweit und noch wichtiger" ist alles, was mit Volatilität zu tun hat, im Standard etwas unklar. "Nein, ist es nicht._" Viele Leute denken, dass es extrem unklar ist. Wenn Sie denken, dass es klar ist, erklären Sie bitte, was es bedeutet, und meine Interpretation ist richtig. – curiousguy