2014-11-28 22 views
20

sto guardando il seguente codice:Qual è il significato di void * * volatili in C++

inline void* interlocked_read_acquire(void* volatile* x); 

e mi chiedo perché non basta un volatile void* come argomento. In generale qual è la semantica o la definizione di uno volatile*? Sto anche ipotizzando che si possa usare il qualificatore volatile* con qualsiasi altro tipo oltre a vuoto. È corretto?

+0

che sembra valido, ma non sono sicuro come leggerlo, così che è il motivo per cui ho chiesto. –

+1

La mia ipotesi per il downvote sarebbe che qualcuno leggesse solo il titolo della domanda e pensava che fosse una domanda senza ricerca su cosa significhi "vuoto" o "volatile" isolatamente. –

+2

@vsoftco sicuramente è piuttosto una sopravvalutazione (tra le persone che seguono comunque il tag C++) - 'volatile' è comunemente noto e lo è anche il significato delle dichiarazioni dei puntatori semplici, quindi anche se questa combinazione specifica non fosse stata vista prima che possa essere elaborato –

risposta

20

Utilizzare cdecl o clockwise spiral rule di decifrare le dichiarazioni in stile C:

void* volatile* x 
  • dichiara x come puntatore al puntatore volatile per invalidare

che è diverso da:

volatile void* x 
  • dichiarare x come puntatore al volatili vuoto
+2

quantdev, 'volatile void' ha senso? O lo fa nel cast? – vsoftco

+2

@vsoftco: ha senso - puoi aggiungere ma non rimuovere 'volatile' durante un' static_cast' (dovresti usare anche 'const_cast'), quindi assicurarti che 'volatile void *' sia 'volatile' aiuta a prevenire accidentalmente rimozione della volatilità quando si accede all'oggetto puntato. –

+0

vuoto volatile ha senso se si presuppone che un vuoto * non punta a un vuoto, punta a qualcosa con un tipo reale ma non si conosce quale tipo. Quindi "vuoto volatile *" significa "potrebbe essere volatile int *, potrebbe essere volatile doppio *, potrebbe essere volatile qualche struttura * ..." – gnasher729

10

chiedersi perché [void* volatile* e] non solo un volatile void* ...?

Sono cose diverse.

  • void* volatile* è un puntatore ad un volatile (void*) (in modo dereferencing e l'accesso alla volatile void* è possibile senza la fusione, ma sarebbe solo dare l'indirizzo di qualche cosa come-ancora non specificata in memoria)

  • volatile void* è un puntatore ad una volatilità void (quindi è necessario eseguire il cast a un tipo come dire volatile int* o volatile My_Class* prima dereferenziando)

7

void * ptr1; significa che ptr1 è una variabile il cui tipo è void *. Questo tipo indica un "puntatore generico": punta a qualche posizione di memoria ma non contiene informazioni sul tipo cosa è in quella posizione.

void * volatile ptr2; significa che la variabile ptr2 è anche un puntatore generico, ma è anche volatile. La parola chiave volatile è denominata qualificatore e ha le stesse regole grammaticali di const.

Il significato di una variabile volatile è che quando un altro codice dice ptr2, il compilatore non può ottimizzarlo; deve leggere o scrivere la posizione di memoria in cui è memorizzato ptr2; deve consentire la possibilità che qualche processo esterno stia anche leggendo o scrivendo quella posizione.

Infine, void * volatile *x è qualcosa che può indicare ptr2. Ad esempio potremmo avere void * volatile * x = &ptr2;.Se quindi scriviamo *x = NULL; ad esempio, allora ha il tipo void * volatile che ha le stesse implicazioni che abbiamo appena visto per ptr2.

Il compilatore si lamenterebbe se ha omesso il qualificatore, ad es. void * *y = &ptr2;. Questo perché l'espressione *y avrebbe quindi il tipo void * (non volatile), quindi il compilatore potrebbe eseguire ottimizzazioni intorno a esso, tuttavia questo comportamento non è corretto perché ptr2 non consente tali ottimizzazioni. (Si può riconoscere che "volatilità-correttezza" è lo stesso tipo di cosa come la costituttezza).

-1

volatile è un add-on di proprietà, è possibile prima rimuoverla per leggere da

void* volatile* x 

a:

void* *x 

Questo è molto familiare. Ad esempio, una serie di puntatori di memoria malloc-ed. E non sarà possibile ottenere confuso con

volatile void* 

che si riduce a

void* x. 
Problemi correlati