2015-12-15 19 views
9

Ci sono due regole correlate C standard:Conversione di un puntatore non `void` a `uintptr_t` e viceversa

C99 standard 6.3.2.3:

Un puntatore a void può essere convertito o da un puntatore a qualsiasi tipo di oggetto o incompleto . Un puntatore a qualsiasi tipo di oggetto o incompleto può essere convertito in un puntatore a vuoto e viceversa; il risultato deve corrispondere a uguale al puntatore originale.

E 7.20.1.4:

Il seguente tipo designa un tipo intero senza segno con la proprietà che ogni puntatore valido vuoto può essere convertito in questo tipo, poi riconvertiti puntatore a void, e il risultato confronterà uguale al puntatore originale: uintptr_t

significa, che il followin codice G è compatibile con:

int *p = NULL; 
void *q = (void*)p; 
uintptr_t s = (uintptr_t)q; 

Ma ha davvero bisogno il cast in due fasi? Sarà il compilatore eseguire un cast intermedio implicita se fare qualcosa di simile:

int *p = NULL; 
uintptr_t s = (uintptr_t)p; 

(Beh, probabilmente il maggior parte dei compilatori, ma la mia domanda è circa la compatibilità standard)

+0

Si noti che 'p' non è inizializzato in entrambi. Probabilmente qualcosa del tipo: 'int i = 42; int * p = & i; ... 'lo aggiusterà. –

+0

@ l3x bene, sì, grazie. Per ragioni di completezza lo risolverà. –

risposta

7

non vorrei rischiare. Lo standard rende abbondantemente chiaro ciò che è permesso e ciò che non è permesso.

Scrivere uintptr_t s = (uintptr_t)(void*)p; segnali a un lettore del tuo codice che sai cosa stai facendo.

+3

Onestamente, se vedessi quel codice, mi chiedevo se l'autore sapeva cosa stavano facendo. In parte perché non avrei un ricordo completo dei passaggi rilevanti dallo standard in questione. Non sto dicendo che sia sbagliato scriverlo in quel modo, ma non mi sembrerebbe altrettanto corretto. –

+2

In tal caso, non ci sarebbe alcun danno nello scrivere un commento. Dipende dalle politiche della tua casa – Bathsheba

Problemi correlati