C++ 警告:类型为‘;无效*’;用于算术

C++ 警告:类型为‘;无效*’;用于算术,c++,pointers,void-pointers,pointer-arithmetic,C++,Pointers,Void Pointers,Pointer Arithmetic,我正在从内存映射中写入和读取寄存器,如下所示: //READ return *((volatile uint32_t *) ( map + offset )); //WRITE *((volatile uint32_t *) ( map + offset )) = value; warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith] 但是,编译器会向我发出如下警告: //READ return *((vo

我正在从内存映射中写入和读取寄存器,如下所示:

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

//WRITE
*((volatile uint32_t *) ( map + offset )) = value;
warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
但是,编译器会向我发出如下警告:

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

//WRITE
*((volatile uint32_t *) ( map + offset )) = value;
warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]

如何更改代码以删除警告?我使用C++和Linux。

类型空洞是不完全类型。它的大小不详。因此,指针指向void的指针算法没有意义。必须将指向void类型的指针转换为其他类型的指针,例如指向char的指针。


还要考虑的是,您可能不会分配使用限定符volatile声明的对象。

因为
void*
是指向未知类型的指针,您不能对其执行指针运算,因为编译器不知道指向的对象有多大

最好的方法是将
map
转换为一个字节宽的类型,然后执行算术运算。您可以为此使用:

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

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

如果在空指针上使用算术是您真正想要的,因为GCC使之成为可能(请参阅),您可以使用
-Wno-pointer-arith
来抑制警告。

强制转换为
char*
-假设您想要字节偏移量。是吗?是的,这是正确的映射为void*,谢谢。您需要将
map
转换为指向大小为1的类型的指针。标准保证大小为1的唯一类型是
char
,因此您需要将其强制转换为
char*
@barakmanos:
char
和变体(
signed char
unsigned char
),因此这是一个令人惊叹的3种大小
1
!但是void*是一个众所周知的类型,它是一个地址类型,它可以指向任何地址类型。。。我猜解决方案是将其静态强制转换为uintpttr\u t*,然后将其强制转换为
char
,因为
sizeof(char)
被定义为1。@Artyer
uint8\u t
更受欢迎,并保证大小为1字节。@VictorPolevoy Only
uint8\u t
保证大小为1字节,因为
uint8\t
不一定存在(我知道这在实践中永远不会发生,但仍然存在)。另外,
uint8\u t
表示“8位数字,
char
表示“字节”,而
offset
是字节偏移量。@Artyer呃,我至少不知道
uint8\u t
,谢谢。但我一直认为
char
是一个“字符”,而
uint8\u t
是一个“字节”,我一直都错了吗另外,从锈中回到C++,听起来很奇怪,<>代码> uTI88t不保证存在: