警告:算术中使用的“void *”类型指针
Posted
技术标签:
【中文标题】警告:算术中使用的“void *”类型指针【英文标题】:warning: pointer of type ‘void *’ used in arithmetic 【发布时间】:2015-01-01 13:16:02 【问题描述】:我正在从内存映射中写入和读取寄存器,如下所示:
//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。
【问题讨论】:
转换为char*
- 假设你想要 byte 偏移量。你呢?
是的,地图是无效的*,谢谢。
您需要将map
转换为指向大小为1 的类型的指针。标准保证大小为1 的唯一类型是char
,因此您需要将其转换为@ 987654326@.
@barakmanos: char
和变体(signed char
,unsigned char
),所以这是一个惊人的 3 种尺寸 1
!
【参考方案1】:
由于void*
是一个指向未知类型的指针,因此您无法对其进行指针运算,因为编译器不知道所指向的对象有多大。
最好的办法是将map
转换为一个字节宽的类型,然后进行算术运算。您可以为此使用uint8_t
:
//READ
return *((volatile uint32_t *) ( ((uint8_t*)map) + offset ));
//WRITE
*((volatile uint32_t *) ( ((uint8_t*)map)+ offset )) = value;
【讨论】:
但是 void * 是一个众所周知的类型,它是一个地址类型,它可以指向任何地址类型...我想解决方案是静态转换为 uintptr_t *,然后 转换为char
会更惯用,因为sizeof(char)
被定义为1。
@Artyer uint8_t
更受欢迎,并且保证大小为 1 字节。
@VictorPolevoy 只有uint_least8_t
保证大小为1 字节,因为uint8_t
不保证存在(我知道这在实践中永远不会发生,但仍然如此)。另外,uint8_t
表示“8 位数字”,char
表示“字节”,offset
是字节偏移量。
@Artyer 呃,我从来不知道uint_least8_t
,谢谢。但是我一直认为char
是一个“字符”,而uint8_t
是一个“字节”,我一直都错了吗? :) 另外,从 Rust 回到 C++ 听起来很奇怪,uint8_t
不能保证存在 :)【参考方案2】:
类型 void 是不完整类型。它的大小是未知的。所以带有指向 void 的指针的指针算术没有意义。您必须将类型为 void 的指针转换为其他类型的指针,例如指向 char 的指针。 还要考虑到您不能分配使用限定符 volatile 声明的对象。
【讨论】:
【参考方案3】:如果对 void 指针使用算术确实是您想要的,因为 GCC 可以实现(请参阅 Arithmetic on void- and Function-Pointers),您可以使用 -Wno-pointer-arith
来抑制警告。
【讨论】:
以上是关于警告:算术中使用的“void *”类型指针的主要内容,如果未能解决你的问题,请参考以下文章