我正在调查我的团队使用size_t
vs int
(或long
等)的标准.我看到的最大的缺点是,两个size_t对象的区别可能会导致问题(我不确定具体的问题 - 可能是某些东西没有补充,而签名/无符号会使编译器生气).我使用V120 VS2013编译器在C++中编写了一个快速程序,允许我执行以下操作:
#includemain() { size_t a = 10; size_t b = 100; int result = a - b; }
该程序导致了-90
,虽然正确,但让我对类型不匹配,有符号/无符号问题感到紧张,或者如果size_t恰好用于复杂的数学运算,则会让我感到紧张.
我的问题是,使用size_t对象进行数学运算是否安全,具体而言,区别对待?我正在考虑使用size_t作为索引之类的标准.我在这里看到了一些关于这个主题的有趣帖子,但是他们没有解决数学问题(或者我错过了它).
减去2 size_t的类型是什么?
typedef是否可以包含size_t的签名类型?
这不保证可以移植,但也不是UB.代码必须无错误地运行,但结果int
值是实现定义的.因此,只要您在保证所需行为的平台上工作,这很好(只要差异可以由int
当然表示),否则,只需在任何地方使用签名类型(参见最后一段).
减去两个std::size_t
s将产生新的std::size_t
†,其值将通过包装确定.在你的例子中,假设64位size_t
,a - b
将相等18446744073709551526
.这不适合(常用的32位)int
,因此分配了实现定义的值result
.
说实话,我建议不要使用无符号整数除了有点神奇.标准委员会的几位成员同意我的意见:https://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything 9:50,42:40,1 :02 : 50
经验法则(从上面的视频中解读Chandler Carruth):如果你能自己计算,请使用int
,否则使用std::int64_t
.
†除非其转换等级小于int
,例如,如果std::size_t
是unsigned short
.在这种情况下,结果是一个int
,一切都会正常工作(除非int
不是更宽short
).然而
我不知道有任何平台可以做到这一点.
这仍然是特定于平台的,请参见第一段.
如果你不使用size_t
,你就搞砸了:size_t
是一种存在用于内存大小的类型,因此保证总是足够大以达到这个目的.(uintptr_t
非常相似,但它既不是第一个这样的类型,也不是标准库使用的,也没有包括它stdint.h
.)如果你使用a int
,当你的分配超过2GiB的地址空间时,你可以得到未定义的行为(或者32kiB,如果你在一个int
只有16位的平台!),即使机器有更多的内存,你正在64位模式下执行.
如果您需要的差异size_t
可能会变为负数,请使用已签名的变体ssize_t
.