数组索引的类型:有符号/无符号整数先锋

Type for array indices: signed/unsigned integer avantages

本文关键字:符号 无符号整数 先锋 索引 类型 数组      更新时间:2023-10-16

在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中尝试使用无符号类型作为数值++充满了问题。如果你担心尺寸太大以至于它们不适合intptrdiff_t将是适当的;毕竟,这是指针或迭代器相减的结果。(事实上v.size()具有与v.end() - v.begin()不同的类型这确实是标准库中的一个设计缺陷。)

对我来说,无符号大小总是最有意义的,因为数组中不能有-32个元素,所以总是将大小/长度视为有符号量是非常可怕的。

你提到的角落案例可以进行编码,例如,如果第一个案例的v为空,你可以在进入循环之前中止循环(从一开始就不那么常见,迭代除最后一个元素之外的所有元素?)。