基本“int”类型的好处在于,对于您当前正在编译的任何平台,它几乎总是最快的整数类型。
另一方面,使用 int32_t(而不仅仅是 int)的优势在于,无论在什么平台上编译,您的代码都可以依赖始终为 32 位宽的 int32_t,这意味着您可以安全地做出更多假设关于值的行为比使用 int 可以。对于固定大小的类型,如果您的代码完全在新平台 Y 上编译,那么它的行为更有可能与在旧平台 X 上完全相同。
int32_t 的(理论上)缺点是新平台 X 可能不支持 32 位整数(在这种情况下,您的代码根本不会在该平台上编译),或者它可能支持它们但处理它们的速度比处理普通的慢旧整数。
上面的例子有点做作,因为几乎所有现代硬件都在全速处理 32 位整数,但是确实存在(并且确实)存在操作 int64_ts 比操作 int 慢的平台,因为 (a) CPU 具有 32 位寄存器,因此必须将每个操作分成多个步骤,当然 (b) 64 位整数将占用 32 位整数的两倍内存,这会给缓存带来额外压力。
但是:请记住,对于人们编写的 99% 的软件,这个问题不会对性能产生任何明显的影响,因为现在 99% 的软件都不受 CPU 限制,甚至对于也就是说,整数宽度不太可能成为主要的性能问题。所以它真正归结为,你希望你的整数数学表现如何?
如果您希望编译器保证您的整数值始终占用 32 位 RAM,并且始终“环绕”在 2^31(或 2^32 无符号),无论您在什么平台上编译,去与 int32_t (等)。
如果您并不真正关心包装行为(因为您知道整数永远不会包装,因为它们存储的数据的性质),并且您想让代码对于奇怪/不寻常的编译目标更具可移植性,并且至少在理论上更快(尽管在现实生活中可能不是),那么您可以坚持使用普通的旧 short/int/long。
我个人默认使用固定大小的类型(int32_t 等),除非有非常明确的理由不这样做,因为我想尽量减少跨平台的变体行为数量。例如,这段代码:
for (uint32_t i=0; i<4000000000; i++) foo();
...将始终准确地调用 foo() 4000000000 次,而这段代码:
for (unsigned int i=0; i<4000000000; i++) foo();
可能会调用 foo() 4000000000 次,或者它可能会进入无限循环,具体取决于 (sizeof(int)>=4) 与否。当然,可以手动验证第二个代码段在任何给定平台上都不会这样做,但是鉴于两种样式之间的性能差异可能为零,我更喜欢第一种方法,因为预测它的行为是不行的脑筋急转弯。我认为 char/short/int/long 方法在 C 的早期更有用,当时计算机体系结构更加多样化,CPU 足够慢,实现完整的本机性能比安全编码更重要。