在日常编程中,uint32_t和int作为约定的区别

26
一个人应该在什么时候使用stdint.h中的数据类型?作为一种约定,始终使用它们是正确的吗?像int和short这样的非特定大小类型的设计目的是什么?
4个回答

30

什么时候应该使用stdint.h中的数据类型?

  1. 当编程任务特别指定整数宽度以适应某些文件或通信协议格式时。
  2. 当需要在性能上牺牲一定程度的可移植性时,尤其是在不同平台之间。

作为惯例,总是使用then吗?

事情正在朝那个方向发展。 固定宽度类型是C语言的较新添加。 最初的C只有char,short,int,long和that,这是一种进步,因为它试图在不太具体的情况下适应各种处理器和环境中可用的各种整数大小。 由于C已经有40多年历史了,这表明该策略取得了成功。 许多C代码已编写并成功应对软整数规格大小。 随着对一致性需求的增加,char,short,int,long和long long已经不足(或者至少不那么容易),因此产生了int8_t,int16_t,int32_t和int64_t。 新语言往往需要非常特定的固定整数大小类型和2的补码。 当它们被成功使用时,达尔文式的压力将推动C语言。 我的水晶球说,我们将看到C语言慢慢迁移到使用固定宽度类型。
“像int和short这样的非特定大小类型的设计目的是什么?”

对于适应各种整数宽度(8、9、12、18、36等)和编码(2的补码,1的补码,符号/幅值等)来说,这是一个不错的第一步。如今,许多编程使用大小为2的幂次方的补码整数,人们可能没有意识到在此之前存在许多其他排列方式。另请参见answer


3
据我所知,“int”被设计为CPU(例如寄存器)最有效地处理的数据类型。“long”只是更长,“short”更短(但可以作为寄存器的一半(如x86上的“al”,“ah”))。 - ensc
1
@ensc 对于“最有效率的CPU”或更接近“本机”CPU整数大小,同意使用int。但是对于一些CPU来说并非总是如此,因为一些旧CPU和今天的小型嵌入式CPU具有“本机”8位整数。但是C要求int至少为16位才能符合标准。 - chux - Reinstate Monica
#2是错误的。现在没有任何理由使用普通的“int”(除了与使用int的现有API兼容性),通过使用stdint.h类型的int_fast16_t(等等),您可以获得可移植性和性能。 - Jetski S-type

5

我的工作需要我使用它们,我实际上很喜欢使用它们。

当我必须实现协议并在结构内使用它们时,我发现它们非常有用,这个结构可以是一个需要发送出去的消息或者某些信息的容器。

如果我需要使用一个需要递增的序列号,我不会使用int,因为序列号不应该是负数。相反,我使用uint32_t。因此,我将知道序列号空间,并且可以进行计划和编码。

我们编写的代码将在32位和64位机器上运行,因此在不同的位机器上使用"int"会导致微妙的错误,这可能很难识别。使用unint16_t将在32或64位架构上分配16位。


在32位系统和64位系统上,uint32_t之间的语义差异以及与int之间的差异可能会对没有使用大量显式转换的代码造成严重破坏。有符号类型之间的交互往往更加“明智”。 - supercat

3

不,我认为在一般编程中使用它们从来都不是一个好主意。

如果您真的关心位数,那么可以使用它们,但对于大多数一般用途来说,您不需要关注位数,因此使用一般类型即可。一般类型可能更快,并且肯定更易于阅读和编写。


1
@anishsane:是的,但如果你在一个16位平台上工作,即使16位(“本地”int)足够使用,始终使用32位整数会减慢程序速度。 - Matteo Italia
1
@MatteoItalia 这就是为什么你要使用uint_least8_t或者 int_fast16_t...如果你希望代码可移植性,就应该避免使用 int 或者 long,而是使用 uint_leastXX_t, int_fastXX_t, 或经典的 uint32_t - benjarobin
2
@Guy,这可能是你正在使用的实现所需的,但标准相当简单。从7.20.1.1-3中可以看出:“这些类型是可选的。但是,如果实现提供了宽度为8、16、32或64位、没有填充位并且(对于有符号类型)具有二进制补码表示的整数类型,则应定义相应的typedef名称。”你很可能会得到各种不同的解释,确保理解清楚其含义。 - WhozCraig
2
@MatteoItalia:“即使16位足够了”:那么你应该使用uint16_t。 - anishsane
1
@anishsane:不,有些平台/情况下,使用比本机更小的int会导致代码变慢;你需要uint_fast16_t,但普通的unsigned int已经是本机大小并且具有最小所需范围。关键在于,由于它们的定义方式,原始类型已经类似于各种int_fastXX_t,其中XX为short和int的16,long的32和long long的64,并且打字起来不那么笨拙。 - Matteo Italia
显示剩余6条评论

3

只有在确实需要时才应使用固定宽度数据类型(例如在实现传输协议、访问硬件或需要一定范围的值时应使用..._least_...变体)。否则,您的程序将无法适应环境的改变(例如,在10年前使用uint32_t来表示文件大小可能还可以,但是off_t将适应最新需要)。正如其他人所指出的那样,性能可能会受到影响,因为在16位平台上,int可能比uint32_t更快。

int本身因其带符号性而非常问题; 当变量保存strlen()sizeof()的结果时,最好使用例如size_t


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接