2014-11-05 16 views
9

Tôi viết và đọc thanh ghi từ một bản đồ bộ nhớ, như thế này:cảnh báo: con trỏ kiểu 'void *' được sử dụng trong số học

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

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

Tuy nhiên trình biên dịch mang lại cho tôi những cảnh báo như thế này:

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

Tôi làm cách nào để thay đổi mã của mình để xóa cảnh báo? Tôi đang sử dụng C++ và Linux.

+3

truyền sang 'char *' - giả sử bạn muốn * bù trừ * byte *. bạn có khỏe không –

+0

Có đó là bản đồ bên phải là void *, cảm ơn. – user1876942

+0

Bạn cần truyền 'map' đến một con trỏ tới một loại kích thước 1. Kiểu duy nhất được đảm bảo bởi chuẩn là kích thước 1 là' char', do đó bạn cần phải đưa nó vào 'char *'. –

Trả lời

6

Loại void là loại không đầy đủ. Kích thước của nó là không rõ. Vì vậy, số học con trỏ với con trỏ để vô hiệu hóa không có ý nghĩa. Bạn phải bỏ con trỏ để nhập void vào một con trỏ của một số kiểu khác ví dụ như con trỏ trỏ tới char. Cũng đưa vào tài khoản mà bạn có thể không chỉ định một đối tượng khai báo với vòng loại dễ bay hơi.

15

void* là một con trỏ đến một loại không xác định bạn không thể làm số học con trỏ trên nó, như trình biên dịch sẽ không biết điều lớn đến mức nào.

Đặt cược tốt nhất của bạn là để đúc map thành loại rộng byte và sau đó thực hiện phép tính số học. Bạn có thể sử dụng uint8_t cho việc này:

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

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

nhưng void * là một loại nổi tiếng, đó là một loại địa chỉ, nó có thể trỏ đến bất kỳ loại địa chỉ ... Tôi đoán giải pháp là tĩnh đúc nó để uintptr_t *, sau đó – Dmitry

+1

Nó sẽ là thành ngữ hơn để đúc để 'char ', như' sizeof (char) 'được định nghĩa là 1. – Artyer

Các vấn đề liên quan