stdint.h 的类型转换和整数提升如何工作?
How does type conversion and integer promotion work for stdint.h?
在 C 中,我了解标准类型的类型转换、整数提升、转换等,但是 stdint.h 类型如何影响这些?
对于类型排名,规则规定:
- 任何两个有符号整数类型都不应具有相同的等级,即使它们具有相同的表示形式。
- 任何无符号整数类型的等级应等于相应的有符号整数类型的等级,如果有的话。
所以假设一个int是32位的,这是否意味着排名int > int32_t = uint32_t > short int
?
此外,stdint.h 类型是否也受整数提升的影响?例如,如果我尝试将有符号字符添加到 uint32_t,它们都会被提升为无符号整数?
回答你的第一个问题:没有。因为 int32_t
通常用这样的 typedef 定义
typedef int int32_t;
它与 int
相同,并且与 int
具有相同的排名。
回答第二个问题:是的。整数提升仍然适用。 stdint.h 中定义的类型的行为就像它们作为别名的类型一样。
顺便说一句,为了对您的编译器的行为更有信心,您可以通过编写这样的无效代码并仔细查看错误消息来测试编译器中的所有这些东西,这将(如果您有好的编译器)在右侧显示表达式的类型:
void * x = (signed char)-1 + (uint32_t)0;
根据 C 标准
— The rank of any standard integer type shall be greater than the rank
of any extended integer type with the same width.
2 的补码表示的精确整数类型被定义为标准整数类型的 tyoedef 别名。
来自 C 标准(7.20.1.1 Exact-width 整数类型)
- ...and (for the signed types) that have a two’s complement
representation, it shall define the corresponding typedef names.
所以当 int 类型有 32 位时这个关系(对于 2 的补码表示)
int > int32_t = uint32_t > short int
是正确的,除了关系 int > int32_t
前提是类型 int32_t
是由 typedef 声明引入的类型 int
的别名..
Also, are the stdint.h types also subject to integer promotion? For
example if I try to add a signed char to a uint32_t, they will both
get promoted to unsigned ints?
这里unsigned char
类型的对象被提升为int
类型,uint32_t
类型的对象被提升为unsigned int
类型(前提是int
有 32 位)由于整数提升
来自 C 标准
If an int can represent all values of the original type (as restricted
by the width, for a bit-field), the value is converted to an int;
otherwise, it is converted to an unsigned int. These are called the
integer promotions. 58) All other types are unchanged by the integer
promotions.
然后由于通常的算术转换,类型 int
的对象被转换为类型 unsigned int
。
来自 C 标准(6.3.1.8 常用算术转换)
Otherwise, both operands are converted to the unsigned integer type
corresponding to the type of the operand with signed integer type.
注意名称 uint32_t
可以是 typedef 声明引入的类型 unsigned int
的别名。在这种情况下 uint32_t
与 unsigned int
.
的类型相同
在 C 中,我了解标准类型的类型转换、整数提升、转换等,但是 stdint.h 类型如何影响这些?
对于类型排名,规则规定:
- 任何两个有符号整数类型都不应具有相同的等级,即使它们具有相同的表示形式。
- 任何无符号整数类型的等级应等于相应的有符号整数类型的等级,如果有的话。
所以假设一个int是32位的,这是否意味着排名int > int32_t = uint32_t > short int
?
此外,stdint.h 类型是否也受整数提升的影响?例如,如果我尝试将有符号字符添加到 uint32_t,它们都会被提升为无符号整数?
回答你的第一个问题:没有。因为 int32_t
通常用这样的 typedef 定义
typedef int int32_t;
它与 int
相同,并且与 int
具有相同的排名。
回答第二个问题:是的。整数提升仍然适用。 stdint.h 中定义的类型的行为就像它们作为别名的类型一样。
顺便说一句,为了对您的编译器的行为更有信心,您可以通过编写这样的无效代码并仔细查看错误消息来测试编译器中的所有这些东西,这将(如果您有好的编译器)在右侧显示表达式的类型:
void * x = (signed char)-1 + (uint32_t)0;
根据 C 标准
— The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.
2 的补码表示的精确整数类型被定义为标准整数类型的 tyoedef 别名。
来自 C 标准(7.20.1.1 Exact-width 整数类型)
- ...and (for the signed types) that have a two’s complement representation, it shall define the corresponding typedef names.
所以当 int 类型有 32 位时这个关系(对于 2 的补码表示)
int > int32_t = uint32_t > short int
是正确的,除了关系 int > int32_t
前提是类型 int32_t
是由 typedef 声明引入的类型 int
的别名..
Also, are the stdint.h types also subject to integer promotion? For example if I try to add a signed char to a uint32_t, they will both get promoted to unsigned ints?
这里unsigned char
类型的对象被提升为int
类型,uint32_t
类型的对象被提升为unsigned int
类型(前提是int
有 32 位)由于整数提升
来自 C 标准
If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 58) All other types are unchanged by the integer promotions.
然后由于通常的算术转换,类型 int
的对象被转换为类型 unsigned int
。
来自 C 标准(6.3.1.8 常用算术转换)
Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
注意名称 uint32_t
可以是 typedef 声明引入的类型 unsigned int
的别名。在这种情况下 uint32_t
与 unsigned int
.