为什么 sizeof(0xF) 是 4 个字节?

why sizeof(0xF) is 4 bytes?

我有以下代码,

unsigned short code = 0x12E0;
code = code & 0x0FFF;

在我的 CLion IDE 中,我收到一条警告

"Values of type int may not fit into the receiver type unsigned short"

如果我把它写成 code &= 0x0FFF;,警告就消失了。

为什么把0x0FFF当成intsizeof(0xF)4,谁能解释为什么?

因为整数常量的类型被确定为第一个可以包含它的类型,而 short 根本不在类型列表中。 int 是第一个适合的类型。

引用 N1570/6.4.4.1p5:

The type of an integer constant is the first of the corresponding list in which its value can be represented.

Suffix | Decimal Constant | Octal or Hexadecimal Constant
------ | ---------------- | -----------------------------
none   | int              | int 
       | long int         | unsigned int
       | long long int    | long int
       |                  | unsigned long int
       |                  | long long int
       |                  | unsigned long long int

table明确指定int为第一种类型,而不是short

没有附加任何特定的后缀,像 0x12E00x0FFF 这样的整数常量是 int 类型。由于 0x.

的前缀,它们将被归类为 "hexadecimal constant"

此外,如 中所述,对于没有显式后缀的整数常量(具体来说,“八进制或十六进制常量”),类型将根据以下列表

中排名最低的排名类型决定
  • int
  • unsigned int
  • long int
  • unsigned long int
  • long long int
  • unsigned long long int

可以容纳(代表)的值。

此外,出于这个原因,sizeof(0xF)sizeof(int) 相同,后者恰好在您的平台中产生 4 的结果。

整数常量 0x0FFF 与所有整数常量一样,至少是 int 类型。不过这里没关系。

在表达式 code & 0x0FFF 中,操作数 code0x0FFF 都受隐式整数提升的约束,整数提升规则。这适用于 小整数类型 ,例如 short。所以 code 操作数总是被提升为(至少) int 而不管其他操作数的类型。

因此,如果您这样做,您将遇到同样的问题:

unsigned short code = 0x12E0;
unsigned short x = 0x0FFF;
code = code & x;

编译器可能会抑制前两行中的警告,因为它只是简单的赋值。但在最后一行有一个更复杂的表达式,整数溢出可能是一个问题。总的来说,编译器往往与这些警告不一致,因为它们不是强制性的。

迂腐但 100% 安全的代码,没有隐式类型转换,看起来像这样:

code = (unsigned short) ((unsigned int)code & 0x0FFFu);