这个问题大致是这样的,本来试图写一个产生低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吧。