pointeur stricte aliasing: est l'accès via un pointeur « volatile » / référence une solution?

StackOverflow https://stackoverflow.com/questions/2981827

Question

Dans la foulée de un problème spécifique , une auto-réponse et les commentaires à, je voudrais comprendre si elle est une bonne solution, solution de contournement / pirater ou tout simplement faux.

Plus précisément, je réécris le code:

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

:

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

avec un qualificatif de volatile au pointeur.

Supposons simplement que le traitement T comme int dans ma situation est logique. Est-ce un problème accédant par aliasing pointeur résoudre référence volatile?

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 la puissance de l'objet être modifié par des moyens non détectables par une mise en œuvre. Voir 1.9 pour 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.

Était-ce utile?

La solution

peut Volatile ne vous aider à éviter un comportement non défini ici. Donc, si cela fonctionne pour vous avec GCC, de la chance.

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

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

! Pas de problème strict aliasing et aucun problème d'alignement de la mémoire. GCC même poignées memcpy comme une fonction intrinsèque (pas d'appel de fonction est insérée dans ce cas).

Autres conseils

peut Volatile ne vous aider à éviter un comportement non défini ici.

Eh bien, quoi que ce soit en ce qui concerne volatile est pas très claire dans la norme. Je la plupart du temps d'accord avec votre réponse, mais maintenant je voudrais peu en désaccord.

Pour comprendre ce que signifie la volatile, la norme n'est pas clair pour la plupart des gens, notamment des écrivains du compilateur. Il est préférable de penser: lorsque vous utilisez volatile (et seulement quand), C / C ++ est à peu près l'ensemble de haut niveau .

Lors de l'écriture à un lvalue de volatile, le compilateur émettra un magasin ou plusieurs STORE si l'on ne suffit pas (volatile ne signifie pas atomique).

Lors de l'écriture à un lvalue de volatile, le compilateur émettra une charge, ou multiple LOAD si l'on ne suffit pas.

Bien sûr, où il n'y a pas de charge ou STORE explicite, le compilateur juste des instructions qui impliquent un chargement ou STORE.

sellibitze a donné la meilleure solution:. utilisation memcpy pour réinterprétations bits

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top