消除 pointer of type ‘void *’ used in arithmetic告警

        考虑这么一段代码,编译时会产生警告void *指针用于算术运算,那么如果消除这个告警?

ssize_t Send(int sockfd, const void *buf, size_t len, int flags)
{
	size_t sendcount = 0x00;
	ssize_t nsend = 0x00;
	do{
		nsend = send(sockfd, buf + sendcount, len - sendcount, 0);
		if(nsend < 0x00 && errno == EINTR)
			continue;
		else
			return -1;
		sendcount += nsend;
	}while(sendcount != len);

	return sendcount;
}
main.cpp:11:30: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
   nsend = send(sockfd, buf + sendcount, len - sendcount, 0);

        很简单,只需要将那行改成以下这样就行,也就是说,需要将buf类型转换为具体类型的指针即可,在这里改成uint8_t *即可。但是我们会好奇编译器为什么会发出这样的告警。

nsend = send(sockfd, (uint8_t *)buf + sendcount, len - sendcount, 0);

        编写测试代码如下,编译后我们进行反汇编。可以发现转换到汇编角度,并非简单的算术加减。是需要乘于其步长即指向类型的占用内存大小。因为编译器并不知道void *真正指向的类型内存大小,所以发出警告。修改需要根据程序上下文语义转换为具体类型的指针,在这里buf+sendcount目的是按字节移动指针,因此转换成uint8_t *即可。

  •         ptr16 += 0x01  对应于  ptr16 += 0x01 * sizeof(uint16)
  •         ptr32 += 0x02  对应于  ptr32 += 0x02 * sizeof(uint32)
#include <unistd.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
	uint8_t *ptr = new uint8_t[32];

	uint16_t *ptr16 = (uint16_t *)ptr;
	ptr16 += 0x01;
	*ptr16 = 0x01;

	uint32_t *ptr32 = (uint32_t *)ptr;
	ptr32 += 0x02;
	*ptr32 = 0x02;
	
	delete ptr;
	ptr = NULL;
	
	return 0;
}
(gdb) disassemble main
Dump of assembler code for function main(int, char**):
   ...
   0x0000000000400661 <+20>:    callq  0x400530 <_Znam@plt>	# new申请内存
   0x0000000000400666 <+25>:    mov    %rax,-0x18(%rbp)		# 返回值放入局部变量ptr
   0x000000000040066a <+29>:    mov    -0x18(%rbp),%rax		# 局部变量ptr的值放入rax寄存器
   0x000000000040066e <+33>:    mov    %rax,-0x10(%rbp)		# 寄存器rax(等于ptr)放入ptr16
   0x0000000000400672 <+37>:    addq   $0x2,-0x10(%rbp)		# ptr16 += 0x02;
   0x0000000000400677 <+42>:    mov    -0x10(%rbp),%rax		# 取出ptr16的值放入rax
   0x000000000040067b <+46>:    movw   $0x1,(%rax)		# *ptr16 = 0x01;
   0x0000000000400680 <+51>:    mov    -0x18(%rbp),%rax		# 局部变量ptr的值放入rax寄存器
   0x0000000000400684 <+55>:    mov    %rax,-0x8(%rbp)		# 寄存器rax(等于ptr)放入ptr32
   0x0000000000400688 <+59>:    addq   $0x8,-0x8(%rbp)		# ptr32 += 0x08;
   0x000000000040068d <+64>:    mov    -0x8(%rbp),%rax
   0x0000000000400691 <+68>:    movl   $0x2,(%rax)		# *ptr32 = 0x02
   ...



  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值