数组索引的类型:有符号/无符号整数先锋
Type for array indices: signed/unsigned integer avantages
在C++中,数组索引的默认大小是size_t,在大多数x86-64平台上,它是一个64位无符号64位整数。我正在为我的高性能计算库构建我自己的std::vector类(其中一个主要原因是我希望这个类能够获得指针的所有权,而std::vector没有提供这一点)。对于数组索引的类型,我考虑使用:
- 大小_t
- 我自己的index_t将是签名的int或长签名的int,具体取决于我的程序
与无符号整数相比,使用有符号整数有很多优点,例如
for (index_t i = 0; i < v.size() - 1; ++i)
它的工作原理就像假设的那样(对于一个无符号整数,当v的大小为0时,这个循环会变得疯狂)
for (index_t i = v.size() - 1; i >= 0; --i)
像它应该做的那样的作品,以及许多其他先锋作品。就性能而言,它甚至看起来比好一点
a + 1 < b + 1
可以减少到<b带有带符号整数(溢出未定义),而不是无符号整数。唯一前卫的性能似乎是,a/=2可以简化为使用无符号整数的移位运算,但不能使用有符号整数。
我想知道为什么C++委员会决定对size_t使用无符号整数,因为这似乎带来了很多痛苦,但优点却很少。
在中使用无符号类型作为索引或大小的动机该标准基于仅与16位相关的约束机器。C++中任何积分类型的自然类型是int
,这可能是应该使用的;就像你一样注意,在C中尝试使用无符号类型作为数值++充满了问题。如果你担心尺寸太大以至于它们不适合int
、ptrdiff_t
将是适当的;毕竟,这是指针或迭代器相减的结果。(事实上v.size()
具有与v.end() - v.begin()
不同的类型这确实是标准库中的一个设计缺陷。)
对我来说,无符号大小总是最有意义的,因为数组中不能有-32个元素,所以总是将大小/长度视为有符号量是非常可怕的。
你提到的角落案例可以进行编码,例如,如果第一个案例的v
为空,你可以在进入循环之前中止循环(从一开始就不那么常见,迭代除最后一个元素之外的所有元素?)。
- 为什么 std::(i)ostream 将有符号/无符号字符视为文本而不是整数
- 警告 C4018:">=":VSC++ 2010 中的有符号/无符号不匹配
- 有符号/无符号不匹配,并且函数在转换为函数时不带2个参数
- 符号"重新声明(有符号/无符号,精度)与
- 有符号/无符号特征编程
- 有符号/无符号 int 不匹配
- 断言(true)警告有符号/无符号不匹配
- 有符号/无符号比较警告是什么意思
- 数组索引的类型:有符号/无符号整数先锋
- 没有兼容的方法来转换相同大小的有符号/无符号
- 溢出的有符号/无符号赋值及其结果
- C++隐式转换(有符号 + 无符号)
- 增强size_type的有符号/无符号比较和multi_array的索引
- 警告 C4018:'>':有符号/无符号不匹配
- c++自动重写有符号/无符号
- C++警告 C4018:"<":有符号/无符号不匹配
- 错误:comp. bet.有符号/无符号整数表达式
- gcc和有符号/无符号比较的奇怪警告行为
- Visual Studio 2013有符号/无符号整数数学行为不同时,求值表达式作为函数参数,编译器切换
- 整数提升,有符号/无符号,和打印