我运行的是一个编码C ++的游戏服务器,还有一些ASM和C。我看到有人更新了我运行的同一台服务器,所有更新中的事实是所有int,unsigned,short以及其他所有内容都更改为int32_t,uint32_t,uint64_t和其他内容。
将所有这些改为上述的那些是否有任何好处?假设我将所有int更改为int32_t,将所有unsigned int更改为uint32_t,当然还有其他所有可能更改的内容。
我试图阅读并理解是否有任何好处,但我根本没有掌握它们的真正含义。所以是的,问题是:做我刚刚说的话有什么好处吗?
我使用的编译器是Orwell Dev-C ++
答案 0 :(得分:3)
正常类型(如int
和unsigned int
)的大小可变,具体取决于您运行的平台。但是,int32_t
和uint32_t
在任何具有32位整数类型的平台上保证为32位。在没有的平台上,它不存在。 int
的大小可能会有所不同,通常为32位或64位长。相同的规则适用于其他类型,例如int64_t
是64位。
要知道网络编程中需要数据类型的大小,因为网络数据包是在具有不同默认整数大小的不同平台之间发送的,而存储在数据包中的数据大小(如地址和端口号)是总是一样。 IPv4地址总是32位长,并且应该使用保证为此大小的数据类型来存储它。
在大多数只存储数字的程序中,您应该使用普通类型。这些在当前平台上的效率最高。
答案 1 :(得分:2)
uint32_t
和int32_t
通过固定大小和符号为数据类型的处理添加更多控制权 - 恕我直言,您在程序中的可预测性越高,就越好。您还可以在typename上看到它是否是无符号的,这可能并不总是不言自明的
使用明确定义的大小,在进行可移植代码时也会受到更多保护。
答案 2 :(得分:1)
实际上,默认的int和long是如此模糊和编译器/平台依赖,我试图避免它们。使用int和long:
对于更多信息类型,如uint32_t或uint_least32_t,您的编译器可能会做出更好的假设并使用64位,如果它认为这会带来更好的性能。我肯定不知道。但是你作为人类有更好的机会去理解你的程序运作良好的价值范围。
此外,所有二进制协议都可能需要指定整数的大小和字节顺序。
答案 3 :(得分:0)
在某些情况下,例如结构字段,我对int32_t
没问题,但是
将您所有的int
写成int32_t
,将unsigned
写成uint32_t
(出于可移植性?)的做法被过度使用;我认为,实际上,您不会从此获得任何实际的可移植性好处,并且存在一些重大缺点。
int
是32位的计算机上编译。如果要将其移植到具有16位int的计算机上,则通常遇到的问题比毯子typedef所能解决的要大得多。int32_t
更改为int
,因为它们中的大多数是计数和索引, 16位计算机的大多数内容不能超过32K,但是人们只是出于习惯而写了它们,如果您将它们保留为int32_t
,则代码将是庞大而缓慢的。int
是将来某个时候的64位吗?由于多种原因,它们不会发生,其中大多数只是实用的事情。int
例如24位。非常不寻常,但是同样,您遇到的问题比typedef所解决的要大,如果移植到这样的野兽,您要做的第一件事可能就是将所有int32_t
更改为{ {1}}。不能解决可移植性问题的原因很多。有什么缺点?
某些库函数具有int
参数,例如frexp。您需要提供一个int变量的地址,否则将无法移植,即使int为32位,int32_t可能也可能不是int(请参见下文)。我见过人们写int *
只是为了使他们可以写frexp( val, (int*)&myvar);
而不是int32_t myvar;
,这很糟糕,并且如果int32_t与int的大小不同,则会产生编译器无法检测到的错误。
与之类似,int myvar;
需要一个int,而不是某种恰好与int大小相同但可能确实很长的typedef,并且如果int32_t为printf( "%d", intvar);
,则gcc / clang会对此发出警告
在许多平台上,long
很长(32位长),尽管int32_t
也是32位,但这很不幸(我认为可以追溯到Microsoft需要在16/32/64上重击,并确定long应该永远是32位,反之亦然)。
在跨平台移植代码时,不确定int32_t是int还是long会导致c ++重载问题。