C++ 将多头、空头和所有整数转换为uint32_t、int32_t等是否有帮助

C++ Does converting long, short and all ints to uint32_t, int32_t and so forth help at all?

本文关键字:有帮助 uint32 是否 int32 整数 C++ 转换      更新时间:2023-10-16

我运行一个编码C++的游戏服务器,那里也有一点ASM和C。我看到有人更新了我运行的同一台服务器,在所有更新中,所有 int、unsign、short 和其他所有内容都已更改为 int32_t、uint32_t、uint64_t 等。

将它们

全部更改为上述内容有什么好处吗?假设我将所有 int 更改为 int32_t,将所有未签名的 int 更改为 uint32_t,当然还有其他所有可以更改的内容。

我试图阅读和理解是否有任何好处,但我根本没有掌握它们的真正含义。所以,是的,问题是:做我刚才说的有什么好处吗?

我使用的编译器是Orwell Dev-C++

普通类型,如 intunsigned int ,根据您运行的平台具有可变的大小。 但是,int32_tuint32_t在任何具有32位整数类型的平台上保证为32位。在没有的平台上,它不存在。int的大小可能会有所不同,通常为 32 或 64 位。相同的规则适用于其他类型,例如int64_t为 64 位。

例如,在网络编程中需要知道数据类型的大小,因为网络数据包在不同的平台之间发送,具有不同的默认整数大小,而存储在数据包中的数据大小(如地址和端口号)始终相同。IPv4地址的长度始终为32位,并且应使用保证为此大小的数据类型来存储它。

在大多数只存储数字的程序中,您应该使用普通类型。这些大小是当前平台上最有效的。

uint32_tint32_t通过具有固定的大小和符号来为数据类型的处理添加更多的控制 - 恕我直言,程序中的可预测性越高,效果就越好。您还可以在字体名称上看到它是否无符号,这可能并不总是不言而喻

使用定义良好的大小,您在执行可移植代码时也受到更多保护。

实际上,默认的 int 和 long 是如此模糊且依赖于编译器/平台,以至于我试图避免它们。使用 int 和 long:

  • 如果你需要知道结构的大小,你需要知道每个体系结构、每个操作系统、每个编译器的 int 和 long 有多少字节。这是对宝贵大脑的浪费。
  • 如果你需要向某人解释该哈希表中发生冲突的概率,你会说"这取决于int的大小,这取决于你的架构",还是宁愿说1.0e-5?换句话说,int 和 long "取消定义"程序的属性。
  • 如果你使用 int,并且编译器发誓它是 64 位,那么它将其优化到 32 或 16 位的可能性很小。因此,如果您想要的只是表示短符号的空间,那么您最终会使用更多的内存......并不是说我知道很多 2^32 个字符的字母表。

对于信息量更大的类型(如 uint32_t 或 uint_least32_t),编译器也许可以做出更好的假设并使用 64 位,如果它认为这将带来更好的性能。我不确定。但是,作为人类,您有更好的机会理解程序运行良好的值范围。

此外,所有二进制协议都可能需要指定整数的大小和字节序。

我在某些情况下对int32_t没有问题,例如结构字段,但是将所有int写成int32_tunsigned写成uint32_t(为了可移植性?)的做法被过度使用;我认为,实际上,您不会从中获得任何真正的可移植性优势,并且存在一些显着的缺点。

  • 您编写的代码很可能只会在int为 32 位的机器上编译。如果你打算把它移植到一台有 16 位整数的机器上,那么你通常会遇到比一揽子 typedef 解决的更大的问题。
  • 如果你确实迁移到 16 位机器,你可能想要更改大量的局部int32_t变量来int 因为它们中的大多数是计数和索引,16 位机器不能有超过 32K 的大多数东西,但人们只是出于习惯而写它们, 如果你把它们留作int32_t代码将是巨大而缓慢的。
  • int将来某个时候是 64 位?不会发生,原因有很多,其中大多数只是务实的事情。
  • 在一些奇怪的机器上,int可能是例如24位。非常不寻常,但同样,您遇到的问题比 typedef 解决的要大,如果移植到这样的野兽,您可能要做的第一件事就是更改所有只是将事情计算回intint32_t

它没有解决便携性问题。有什么缺点?

  • 某些库函数具有int *参数,例如 frexp。您需要提供 int 变量的地址,否则它不会移植,即使 int 是 32 位,int32_t也可能不是 int(见下文)。我见过人们写frexp( val, (int*)&myvar);只是为了他们可以写int32_t myvar;而不是int myvar;,这很糟糕,如果int32_t的大小与 int 不同,可能会产生编译器无法检测到的错误。

  • 同样,printf( "%d", intvar);需要一个 int,而不是一些恰好与 int 大小相同但可能真的很长的 typedef,如果 gcc/clang long,它会发出警告int32_t。

  • 在许多平台上,int32_t很长(32 位长),即使int也是 32 位,这是不幸的(我认为这可以追溯到Microsoft需要扔掉超过 16/32/64 的东西并决定长应该是永远 32 位,反之亦然)。

  • 跨不同平台移植代码时,int32_t是 int 还是 long 的不确定性可能会导致 c++ 重载问题。