我已经知道stdint
用于需要特定变量大小以实现平台之间的可移植性。我现在还没有这样的问题,除了上面已经说明的事实之外,使用它有什么缺点和优点?
在stackoverflow和其他网站上寻找这个,我找到了2个关于主题的链接:
codealias.info - 这个讨论了stdint的可移植性。
stackoverflow - 这个更具体针对 uint8_t 。
如果想要了解更多关于此标题的主要原因 - 可移植性,这两个链接非常棒。但对我而言,我最喜欢的是我认为uint8_t
比unsigned char
更清晰(例如,存储RBG通道值),int32_t
看起来比简单int
更有意义。 1}}等等。
所以,我的问题是,除了可移植性之外,使用stdint
的缺点和优点是什么?我应该只在代码的某些特定部分或任何地方使用它吗?如果到处都是,我如何使用atoi()
,strtok()
等功能呢?
谢谢!
答案 0 :(得分:68)
使用定义良好的类型可以使代码更容易和更安全地移植,因为当一台机器将int
解释为16位而另一台机器解释为32位时,您不会感到惊讶。使用stdint.h,你输入的内容就是你得到的。
使用int
等也很难检测到危险类型的促销活动。
另一个优点是,通过使用int8_t
而不是char
,您知道您总是获得一个带符号的8位变量。 char
可以是有符号或无符号的,它是实现定义的行为,因编译器而异。因此,默认char
在可移植的代码中使用是非常危险的。
如果您想给编译器提示应该优化变量,可以使用uint_fastx_t
告诉编译器使用尽可能快的整数类型,至少和'x'一样大。大多数情况下这无关紧要,编译器足够智能,无论您输入什么内容,都可以对类型大小进行优化。在序列点之间,编译器可以隐式地将类型更改为指定的类型,只要它不影响结果。
无。
参考:MISRA-C:2004规则6.3。“ typedefs 表示大小和签名应用于代替基本类型”。
编辑:删除了错误的示例。
答案 1 :(得分:16)
使用uint8_t
而不是unsigned char
(除了审美偏好)的唯一原因是,如果您想要记录您的程序要求char
恰好为8位。根据C标准的要求,当且仅当uint8_t
存在CHAR_BIT==8
时。
其他intX_t
和uintX_t
类型在以下情况下非常有用:
&
运算符更方便地完成)。memcmp
或散列目的)。另一方面,uint_least8_t
等类型在您希望避免使用浪费的大型或慢速类型的任何地方都很有用,但需要确保您可以存储特定大小的值。例如,虽然long long
至少是64位,但在某些机器上它可能是128位,并且当你需要的只是一种可以存储64位数字的类型时使用它会在这些机器上非常浪费。 int_least64_t
解决了这个问题。
我会完全避免使用[u]int_fastX_t
类型,因为它们有时会在给定的机器上更改(打破ABI),因为定义通常是错误的。例如,在x86_64上,64位整数类型被认为是16位,32位和64位值的“快速”类型,但是无论您使用32位,加法,减法和乘法都是完全相同的速度比特或64比特的值,除了大于必要类型的分数几乎肯定更慢,即使它们是相同的速度,你使用两倍的内存也没有任何好处。
最后,请注意,当一个计数器不是本机整数大小时,对于计数器使用int32_t
的效率低的一些答案在技术上大多数是正确的,但它与正确的代码无关。除非你计算一些最小数量在你控制之下的东西,或者一些外部的(不在你程序的记忆中)计数可能是天文数字的东西,否则计数的正确类型几乎总是{{1} }。这就是为什么所有标准C函数都使用size_t
作为计数。除非你有充分的理由,否则不要考虑使用其他任何东西。
答案 2 :(得分:7)
C语言未指定int
或long
等的大小的主要原因是计算效率。每个体系结构都具有自然,最高效的大小,并且设计人员特别授权并希望编译器实现者使用自然原生数据大小数据来提高速度和代码大小效率。
过去几年,与其他机器的通信并不是主要问题 - 大多数程序都是机器的本地程序 - 所以每种数据类型的大小的可预测性几乎不受关注。
坚持特定体系结构使用特定大小int
来计算是一个非常坏主意,即使它似乎使其他事情变得更容易。
在某种程度上,由于XML及其兄弟,数据类型的大小再次不再是一个问题。从机器到机器的特定于机器的二进制结构也是例外,而不是规则。
答案 3 :(得分:6)
我只使用stdint类型有一个原因,当我在内存中保存的数据应以二进制形式存在于磁盘/网络/描述符上时。你只需要对抗小端/大端问题,但那是相对easy to overcome。
不使用stdint的显而易见的原因是代码与大小无关,在数学术语中,所有东西都适用于有理整数。如果您为uint*_t
的每次扩展提供qsort()
版本,例如*
,则会产生难看的代码重复。
在这种情况下,我使用自己的类型,当我懒惰时从size_t
派生,或者当我不是时,从平台上获得最大支持的无符号整数。
编辑,因为我之前遇到过这个问题:
我认为值得注意的是,至少uint8_t
,uint32_t
和uint64_t
在Solaris 2.5.1中已被破坏。
因此,为了获得最大的可移植性,我仍然建议避免stdint.h
(至少在接下来的几年内)。