Rigorosa puntatore aliasing: è l'accesso attraverso un 'volatili' puntatore / riferimento una soluzione?

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

Domanda

Sulla scia di un problema specifico , un auto-risposta e commenti ad esso, mi piacerebbe capire se si tratta di una soluzione adeguata, soluzione / hack o semplicemente sbagliato pianura.

In particolare, ho riscritto il codice:

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

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

con un qualificatore volatile al puntatore.

Diamo per scontato che il trattamento T come int nella mia situazione ha un senso. Questo l'accesso tramite un riferimento volatile risolvere puntatore problema aliasing?

Per un riferimento, da specifica:

[Nota: volatile è un suggerimento per l'attuazione di evitare aggressivo ottimizzazione coinvolge l'oggetto in quanto il valore della potenza dell'oggetto essere modificate mediante rilevabili da un'implementazione. Vedere 1.9 per semantica dettagliate. In generale, la semantica di volatili sono destinati essere la stessa in C ++ come sono in C. - nota fine]

EDIT:

Il codice di cui sopra ha risolto il mio problema almeno su GCC 4.5.

È stato utile?

Soluzione

Può volatile non aiuta a evitare un comportamento indefinito qui. Quindi, se funziona per voi con GCC che di fortuna.

Supponiamo che T è un POD. Quindi, il modo corretto per farlo è

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

! Nessun problema rigorosa aliasing e nessun problema di allineamento di memoria. GCC anche maniglie memcpy come funzione intrinseca (senza chiamata di funzione viene inserita in questo caso).

Altri suggerimenti

Può volatile non aiuta a evitare un comportamento indefinito qui.

Bene, nulla per quanto riguarda volatile è un po 'poco chiaro nella norma. Io per lo più d'accordo con la risposta, ma ora vorrei non essere d'accordo un po '.

Per capire cosa significa volatile, lo standard non è chiaro per la maggior parte delle persone, in particolare alcuni scrittori del compilatore. E 'meglio pensare: quando si utilizza volatile (e solo quando), C / C ++ è più o meno alto livello di assieme .

Quando si scrive a un lvalue volatile, il compilatore emetterà un negozio, o di memorizzare più, se uno non è sufficiente (volatile non implica atomico).

Quando si scrive a un lvalue volatile, il compilatore emetterà un carico, o di caricare più se uno non è sufficiente.

Naturalmente, dove non c'è LOAD esplicita o STORE, il compilatore sarà solo impartire istruzioni che implicano un LOAD o STORE.

sellibitze ha dato la soluzione migliore:. uso memcpy per reinterpretazioni bit

Ma se tutti gli accessi ad una regione di memoria sono fatti con lvalue volatile, è perfettamente chiaro che le rigide regole di aliasing non si applicano . Questa è la risposta alla tua domanda.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top