2010-06-05 8 views
8

Sur les talons de a specific problem, une auto-réponse et des commentaires, je voudrais comprendre si c'est une solution appropriée, solution de contournement/hack ou tout simplement faux.Alias ​​de pointeur strict: l'accès via un pointeur 'volatile'/référence une solution?

Plus précisément, je Code récrit:

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

Comme:

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

avec un qualificatif volatile au pointeur. Supposons simplement que le traitement T comme int dans ma situation est logique. Est-ce que cet accès via une référence volatile résout un problème d'aliasing de pointeur?

Pour une référence, de la spécification:

[Note: volatile est une allusion à la mise en œuvre pour éviter agressive optimisation impliquant l'objet parce que la valeur de l'objet peut être modifié par indétectables par un la mise en oeuvre. Voir 1.9 pour la sémantique détaillée . En général, la sémantique des volatiles sont destinées être le même en C++ comme ils sont en C. - Note de fin]

EDIT:

Le code ci-dessus ne résout mon problème au moins sur GCC 4.5 .

+0

Cette question n'est pas ** clairement spécifique à C++. Les distributions de style C++ peuvent être réécrites en C. – curiousguy

+0

@curiousguy C et C++ ont des règles de langage différentes cependant –

+0

@MattMcNabb Comment sont les différents WRT 'volatile'? – curiousguy

Répondre

15

Volatile ne peut pas vous aider à éviter un comportement indéfini ici. Donc, si cela fonctionne pour vous avec GCC, c'est de la chance.

Supposons que T est un POD. Ensuite, la bonne façon de le faire est

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

Là! Aucun problème d'aliasing strict et aucun problème d'alignement de la mémoire. GCC gère même memcpy comme une fonction intrinsèque (aucun appel de fonction n'est inséré dans ce cas).

+1

"Volatile ne peut pas vous aider à éviter un comportement indéfini ici" - pourquoi? Avez-vous une source pour cette déclaration? – doublep

+5

Norme C++, section 3.10, paragraphe 15, est l'endroit que vous devez prendre en compte en ce qui concerne l'aliasing strict. Il n'y a aucune mention d'une exception impliquant volatile. – sellibitze

+0

Il existe des cas où ce comportement n'est pas indéfini. Par exemple 'struct A {int a; } int main() {X x; * reinterpret_cast (& x) = 10; } 'est bien et parfaitement défini selon '9.2/17'. L'objet est de type 'int', et le lvalue est aussi de type' volatile int', donc l'aliasing va bien. –

-3

Volatile ne peut pas vous aider à éviter un comportement indéfini ici.

Eh bien, tout ce qui concerne volatile n'est pas très clair dans la norme. Je suis surtout d'accord avec votre réponse, mais maintenant je voudrais être légèrement en désaccord.

Pour comprendre ce que volatile signifie, la norme n'est pas claire pour la plupart des gens, notamment certains auteurs de compilateurs. Il est préférable de penser: lors de l'utilisation volatile (et seulement quand), C/C++ est à peu près haut niveau d'assemblage.

Lors de l'écriture à un volatile lvalue, le compilateur émettra un magasin ou plusieurs STORE si l'on est pas assez (volatile ne signifie pas atomique). Lors de l'écriture dans une lvalue volatile, le compilateur lance une LOAD, ou plusieurs CHARGE si celle-ci n'est pas suffisante.

Bien sûr, là où il n'y a pas de LOAD ou de STORE explicite, le compilateur lancera simplement des instructions qui impliquent une LOAD ou une STORE. Sellibitze a donné la meilleure solution: utiliser memcpy pour les réinterprétations de bits.

Mais si tous les accès à une zone de mémoire sont fait avec volatile lvalues, il est parfaitement clair que les règles strictes de crénelage ne sont pas applicables. Ceci est la réponse à votre question.

+0

Pourquoi la downvote? – curiousguy

+6

-1: D'abord, ce n'est pas un forum; nous n'abordons pas d'autres réponses dans les réponses. Si vous pensez que vous avez une meilleure réponse, alors écrivez une réponse qui répond à la question. Deuxièmement et plus important encore, "tout ce qui concerne les volatiles est quelque peu flou dans la norme." Non, ça ne l'est pas. La norme est * très * claire sur le fonctionnement de la machine abstraite en termes de volatilité et de non-volatilité. –

+1

@NicolBolas "_Second et surtout," tout ce qui concerne volatile n'est pas clair dans la norme. "Non, ce n'est pas._" Beaucoup de gens pensent que ce n'est pas clair. Si vous pensez que c'est clair, veuillez expliquer ce que cela signifie, et mon interprétation est correcte. – curiousguy

Questions connexes