2010-03-19 9 views
22

Betrachten Sie den folgenden Code ein:Warum ist 'flüchtige' Parasiten in C++?

int main()                  
{                    
    int i;                  
    volatile int* p = &i;              
    int *v = p;                 
    return 0;                 
} 

dies ein Fehler gibt in g++:

$ g++ -o volatile volatile.cpp 
volatile.cpp: In function ‘int main()’: 
volatile.cpp:6: error: invalid conversion from ‘volatile int*’ to ‘int*’ 

Meine Absicht war, dass ich p flüchtig machen wollen. Nachdem ich jedoch den Wert p gelesen habe, ist es mir egal, ob der Zugriff auf v flüchtig ist. Warum ist es erforderlich, dass v für flüchtig erklärt wird?

Dies ist natürlich hypothetischer Code. In einer realen Situation können Sie sich vorstellen, dass auf einen Speicherort zeigt, aber extern geändert wird und ich möchte v auf den Speicherort verweisen, der auf die Zeit v = p wies, auch wenn später p extern geändert wird. Daher ist flüchtig, aber v ist nicht.

Nebenbei interessiert mich das Verhalten sowohl wenn dies als C und C++ betrachtet wird, aber in C erzeugt dies nur eine Warnung, kein Fehler.

+2

Die Standards kennen den Unterschied zwischen einer Warnung und einem Fehler nicht. Es ist die Wahl des Compilers, wie eine Verletzung behandelt wird, solange mindestens eine Nachricht für das Programm gemeldet wird. –

+2

vielleicht möchten Sie eine Kopie von p in v? – slf

Antwort

36

Wenn Sie meinen, dass der Zeiger flüchtig sein sollte, anstatt das Objekt, um es auf die Punkte, dann erklären sie als

int* volatile p; 
+7

Das ist deine Antwort, Steve. Ich möchte diese Empfehlung hinzufügen: * Schreiben Sie immer das const/volatile Qualifikationsmerkmal ** nach dem, was Sie qualifizieren wollten. * Es ist die einzige Möglichkeit, Qualifizierer * konsistent * zu schreiben, da Sie beide "volatile int" schreiben können und 'int volatile', wenn Sie eine volatile Ganzzahl wünschen, aber nur 'int * volatile', erhalten Sie einen flüchtigen * Zeiger *. – DevSolar

+0

Danke !!! Ich habe nicht einmal daran gedacht. Völlig logisch, danke. – Steve

+1

Der einfachste Weg, Deklarationen zu lesen (sowohl für const als auch für volatile Placements), besteht darin, sie einfach rückwärts zu lesen. Daher ist "int * volatile" ein "flüchtiger Zeiger auf einen int". – Adisak

14

In C++ die volatile Stichwort, um die gleiche Art von Einschränkung gilt, was Sie tun können, als const tut. Der Standard bezeichnet dies als "cv-qualification" wie in "const/volatile qualification". Die Verwendung von Konden- saten ist nur bei Kons- tonen möglich, und auf die gleiche Weise können flüchtige Substanzen nur von flüchtigen Substanzen verwendet werden.

Nur als Nebenbemerkung, dies kann Ihnen beim Schreiben von Multithread-Code helfen. Nicht aufgrund der Verwendung einer Compiler-Magie, die Ihre Variable plötzlich atomar oder ähnlich macht, sondern indem Sie gezwungen werden, flüchtige Daten nur flüchtig zu verarbeiten. Siehe hierzu Alexandrescu article für weitere Informationen.

+0

Auch einen Blick wert: http://www.mikeash.com/pyblog/friday-qa-2009-07-10-type-specifiers-in-c-part-3.html (aka. Vergessen Sie nicht über OSMemoryBarrier) – slf