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。@Artyeruint8\u t
更受欢迎,并保证大小为1字节。@VictorPolevoy Onlyuint8\u t
保证大小为1字节,因为uint8\t
不一定存在(我知道这在实践中永远不会发生,但仍然存在)。另外,uint8\u t
表示“8位数字,char
表示“字节”,而offset
是字节偏移量。@Artyer呃,我至少不知道uint8\u t
,谢谢。但我一直认为char
是一个“字符”,而uint8\u t
是一个“字节”,我一直都错了吗另外,从锈中回到C++,听起来很奇怪,<>代码> uTI88t不保证存在: