C 是否有任何理由不使用固定宽度整数类型(例如uint8\u t)?
假设您使用的编译器支持C99(甚至只是stdint.h),那么有没有理由不使用固定宽度的整数类型,比如uint8\t 我知道的一个原因是,在处理字符时使用C 是否有任何理由不使用固定宽度整数类型(例如uint8\u t)?,c,integer,byte,sizeof,c99,C,Integer,Byte,Sizeof,C99,假设您使用的编译器支持C99(甚至只是stdint.h),那么有没有理由不使用固定宽度的整数类型,比如uint8\t 我知道的一个原因是,在处理字符时使用chars比使用(u)int8\ts更有意义,如中所述 但是,如果您计划存储一个数字,您什么时候想使用一个您不知道它有多大的类型?也就是说,在什么情况下,您希望在不知道数字是8位、16位还是32位的情况下,将数字存储在无符号短码中,而不是使用uint16t 在此基础上,使用固定宽度的整数,或者使用普通整数类型,并且永远不要假设任何东西,在需要知
char
s比使用(u)int8\t
s更有意义,如中所述
但是,如果您计划存储一个数字,您什么时候想使用一个您不知道它有多大的类型?也就是说,在什么情况下,您希望在不知道数字是8位、16位还是32位的情况下,将数字存储在无符号短码中,而不是使用uint16t
在此基础上,使用固定宽度的整数,或者使用普通整数类型,并且永远不要假设任何东西,在需要知道它们使用了多少字节的地方使用sizeof
,这被认为是更好的做法吗?实际上,在不需要知道类型的确切大小的情况下存储数字是很常见的。我的程序中有很多数量,我可以合理地假设不会超过20亿,或者强制执行它们不会超过20亿。但这并不意味着我需要一个精确的32位类型来存储它们,任何可以计数到至少20亿的类型我都可以
如果您试图编写非常可移植的代码,那么必须记住,固定宽度类型都是可选的
在CHAR\u BIT
大于8
的C99实现上,没有int8\u t
。标准禁止它存在,因为它必须有填充位,intN\t
类型被定义为没有填充位(7.18.1.1/1)<因此,code>uint8\u t
也被禁止,因为(谢谢,ouah)不允许实现在没有int8\u t
的情况下定义uint8\u t
因此,在非常可移植的代码中,如果您需要一个能够容纳最多127个值的有符号类型,那么您应该根据您是否希望要求编译器生成它,使用signed char
、int
、int\u least8\u t
中的一种:
- 使用C89(
或signed char
)int
- 避免在算术表达式中出现意外的整数提升(
)int
- 小(
或int至少8\t
)signed char
- 快速(
或int\u fast8\t
)int
unsigned char
、unsigned int
、uint\u least8\u t
和uint\u fast8\u t
如果您需要在非常可移植的代码中使用模256算法,那么您可以自己取模,屏蔽位,或者使用位字段玩游戏
实际上,大多数人从来不需要编写可移植的代码。目前,CHAR\u BIT>8
只在专用硬件上出现,而您的通用代码不会在其上使用。当然,这在将来可能会发生变化,但如果真的发生了,我怀疑有太多的代码对Posix和/或Windows(两者都保证CHAR\u BIT==8
)做出假设,那么处理代码的不可移植性将是将代码移植到新平台的巨大努力的一小部分。任何这样的实现都可能需要担心如何连接到互联网(以八位字节为单位),而不是担心如何启动和运行代码:-)
如果您假设
CHAR\u BIT==8
,那么我不认为有任何特别的理由避免(u)int8\u t
,除非您希望代码在C89中工作。即使在C89中,为特定的实现找到或编写一个版本的stdint.h
也不难。但是如果您可以轻松地编写代码,只要求该类型可以容纳255
,而不是要求它不能容纳256
,然后您还可以避免依赖于CHAR\u BIT==8
标准整数类型的宽度确实可以从一个平台更改到另一个平台,但不是其最小宽度
例如,C标准规定int
至少为16位
,long
至少为32位
宽
如果在存储对象时没有一些大小限制,可以将其应用到实现中。例如,如果最大有符号值适合
16位
,则可以使用int
。然后,让实现最终确定实现目标体系结构的自然int
宽度。在假设宽度时,应仅使用固定宽度类型
uint8\t
和unsigned char
在大多数平台上是相同的,但并非在所有平台上都是相同的。使用uint8\u t
强调一个事实,即您假设一个体系结构具有8位char
,并且不会在其他体系结构上编译,因此这是一个特性
否则我会使用“语义”typedef
,比如size\u t
,uintptpr\u t
,ptrdiff\u t
,因为它们更好地反映了您对数据的想法。我几乎从不直接使用基类型,int
只用于返回错误,我也不记得曾经使用过short
编辑:在仔细阅读C11之后,我得出结论,如果存在
uint8\u t
,则它必须是无符号字符
,并且不能只是字符
,即使该类型是无符号的。这源于7.20.1 p1中的要求,即所有intN\u t
和uintN\u t
必须是相应的有符号和无符号类型。字符类型的唯一这一对是有符号字符
和无符号字符
,代码应该向普通读者(以及程序员自己)揭示什么是重要的。是整数还是无符号
uint64_t a,b,c;
...
a &= ~0x40000000;
b &= ~0x80000000;
c &= ~0x100000000;