2014-11-05 14 views
9

sto scrivendo e leggendo i registri da una mappa della memoria, in questo modo:avvertimento: puntatore di tipo 'void *' utilizzato in aritmetica

//READ 
return *((volatile uint32_t *) (map + offset)); 

//WRITE 
*((volatile uint32_t *) (map + offset)) = value; 

Tuttavia il compilatore mi dà avvertimenti come questo:

warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith] 

Come posso modificare il mio codice per rimuovere gli avvisi? Sto usando C++ e Linux.

+3

espressi su 'char *' - presupponendo che si desideri * byte * offset. Fai? –

+0

Sì, quella è la mappa corretta è nullo *, grazie. – user1876942

+0

Devi lanciare 'map' su un puntatore a un tipo di dimensione 1. L'unico tipo garantito dallo standard per essere di dimensione 1 è' char', quindi devi lanciarlo su 'char *'. –

risposta

6

Il vuoto di tipo è incompleto. La sua dimensione è sconosciuta. Quindi il puntatore aritmetico con puntatori a vuoto non ha senso. Devi lanciare il puntatore per digitare void su un puntatore di qualche altro tipo, ad esempio puntatore a char. Considerare anche che non si può assegnare un oggetto dichiarato con qualificatore volatile.

15

Poiché void* è un puntatore a un tipo sconosciuto, non è possibile eseguire l'aritmetica del puntatore su di esso, poiché il compilatore non saprebbe quanto è grande l'oggetto indicato.

La soluzione migliore è quella di trasmettere map a un tipo largo un byte e quindi eseguire l'aritmetica. È possibile utilizzare uint8_t per questo:

//READ 
return *((volatile uint32_t *) (((uint8_t*)map) + offset)); 

//WRITE 
*((volatile uint32_t *) (((uint8_t*)map)+ offset)) = value; 
+0

ma void * è un tipo ben noto, è un tipo di indirizzo, può essere indirizzato a qualsiasi tipo di indirizzo ... Immagino che la soluzione sia il cast statico in uintptr_t *, quindi – Dmitry

+1

Sarebbe più idiomatico eseguire il cast in 'char ', come' sizeof (char) 'è definito come 1. – Artyer