2014-11-05 24 views
9

piszę i czytanie rejestrów z mapy pamięci, tak:ostrzeżenie: wskaźnik typu „void *” używane w arytmetyce

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

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

Jednak kompilator daje mi ostrzeżenia tak:

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

Jak zmienić kod, aby usunąć ostrzeżenia? Używam C++ i Linux.

+3

rzut na "char *" - zakładając, że chcesz * bajt * przesunięcie. czy ty? –

+0

Tak, to jest właściwa mapa jest nieważna *, dziękuję. – user1876942

+0

Musisz rzucić 'map' do wskaźnika na typ rozmiaru 1. Jedynym typem gwarantowanym przez standard dla wielkości 1 jest' char', dlatego musisz go rzucić na 'char *'. –

Odpowiedz

6

Typ void jest niekompletnym typem. Jego rozmiar jest nieznany. Zatem wskaźnik arytmetyczny ze wskaźnikami do pustki nie ma sensu. Musisz rzucić wskaźnik, aby wpisać void do wskaźnika innego typu, na przykład do wskaźnika do znaku. Należy również wziąć pod uwagę, że nie można przypisać obiektu zadeklarowanego z kwalifikatorem volatile.

15

Ponieważ jest wskaźnikiem do nieznanego typu, nie można wykonać na nim arytmetyki wskaźnika, ponieważ kompilator nie wiedziałby, jak duża jest ta rzecz.

Najlepiej jest rzucić map na typ o szerokości bajtowej, a następnie wykonać arytmetykę. Do tego celu można użyć uint8_t:

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

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

ale void * jest dobrze znanym typem, jest typem adresu, może wskazywać na dowolny typ adresu ... Domyślam się, że rozwiązaniem jest statyczny rzut na uintptr_t *, następnie – Dmitry

+1

Byłoby bardziej idiomatycznie rzutować na 'char ', ponieważ' sizeof (char) 'jest zdefiniowane jako 1. – Artyer