C语言隐式类型转换的一个小坑
作者:网络转载 发布时间:[ 2016/11/9 10:15:58 ] 推荐标签:C语言 .NET
这个问题大致是这样的,本来试图写一个产生低8位为1的掩码的语句: uint32_t mask = ~((uint8_t)0); ,结果发现算出的掩码是 0xffffffff 显然不符合预期,于是折腾检查了一番,写出对比程序如下:
#include <stdint.h>
#include <iostream>
using namespace std;
int main()
{
uint8_t z = 0;
uint32_t x = ~(uint8_t)0;
uint32_t y = (uint8_t)~0;
cout << typeid(~(uint8_t)0).name() << endl;
cout << typeid((uint8_t)~0).name() << endl;
cout << x << endl;
cout << y << endl;
}
程序的输出(macOS, Clang)是:
i
h
4294967295
255
所以很显然这两种写法之间的细微区别,导致所产生的结果并不相同。通过 typeid 我们可以看到其实这两个表达式的类型是不同的,后者的 h 显然是表示 uint8_t ,那么前者估计是 int 了。所以目测这里估计是规定了隐式类型转换之类的,果断去翻一下 C99 标准,果不其然, 6.5 节开头规定如下:
然后在 6.5.3.3 又有如下解释:
所以,在这里按位取反运算符实际上是对 uint8_t 进行了整型提升,然后取反的运算结果也是整数类型的 -1 ,当转换为无符号整数的时候自然会导致所有 bit 都是1,而不是期望的只有低位一个字节为1了。
总而言之,语义理解不清晰,果断去翻相应的spec吧。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11