bug记录:常量值截断(truncation of constant value)

char和unsigned char

char的取值范围:-128~127
  -128: 16进制0x80 二进制1000 0000
  -127: 16进制0xff  二进制1111 1111,注意第一位是符号位,0111 1111是127

unsigned char的取值范围:0~255,16进制0x00 ~ 0xff

内存中的0xf0: 1111 0000

char x = 0xf0; // 十进制数大小为240,超出了127,导致常量值截断
if(0xf0 == x){ // x86机器上判断为false,arm机器上可能判断为true
	std::cout << "x == 0xf0" << std::endl;
}
std::cout<< "char x= " << x 
		<< "\tunsigned char x = " << (unsigned char)x 
		<< "\tint x = " << (int)x << std::endl; // 在不同机器上可能出现不同值

mac(m1 arm64)打印结果:

	char x= �	unsigned char x = �	int x = -16  

linux(x86)打印结果和上面一致

arm盒子(arm64)打印结果:

	char x= �	unsigned char x = �	int x = 240

    char和unsigned char乱码,直接看int,一个取值-16,一个取值240
取值为-16的情况:
    int类型时,-16的二进制为 1000 0000| 0000 0000| 0000 0000| 0001 0000,最后一个字节是0001 0000
    而1111 0000 取反为 0000 11111,加1正好是0001 0000,即0xf0的补码是0001 0000,因此在将(char)0xf0变为int类型时的十进制数-16,至于为什么是这样的规则我也不知道。
取值为240的情况:
    int类型时,240的二进制为 0000 0000| 0000 0000| 0000 0000| 1111 0000,最后一个字节就是1111 0000

    综上,有些机器在处理常量截断时是取补码,而有些机器是取正码,即不变。实际上,char x = 0xf0这种用法本身就是错误的,不应该使用,对二进制字节比较时最好选用unsigned char类型。
    不过,在对内存中的二进制字节进行判断时,也可以使用 if(x == (char)0xf0)这种形式。

Note & 猜测:
     char x = 0xf0 虽然发生了常量截断,但是内存中的值确实是0xf0,只不过在从内存中读取出来时不同类型有不同的取值。

参考:
http://www.cplusplus.com/forum/beginner/48577/
https://zhidao.baidu.com/question/533897399.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值