使用size_t来移动矢量索引是否安全?

时间:2016-06-25 13:10:30

标签: c++ integer

我更喜欢使用size_t来处理矢量索引。但是当转移指数时,它是否安全?例如,

size_t n = 10000000;
vector<int> v(n);

size_t i = 500000;
size_t shift = 20000;
int a = v(i - (-1) * shift); // Is this ok? what is `(-1) * shift` type, size_t?
int b = v(-shift + i); // Is this ok? what is `-shift` type, size_t?

3 个答案:

答案 0 :(得分:2)

否定unsigned数量是有效的操作。 C ++ 11的第5.3.2节:

  

无符号数量的负数是通过减去它来计算的   值来自2 ^ n,其中n是提升的位数   操作数。结果的类型是提升的操作数的类型。

所以,这是“安全的”,因为这是定义的行为。

答案 1 :(得分:1)

size_t(-1)相乘是安全的,它包含size_t的最大值,因为size_t是无符号类型。因此(-1) * shiftstd::numeric_limits<size_t>::max-shift+1相同。

答案 2 :(得分:0)

当然,你的意思是v[...]而不是v(); std::vector没有operator(int)

无论如何,凭经验,

#include <iostream>
using namespace std;
int main(){
    unsigned foo = 1;
    cout<<(-1)*foo<<'\n';
    cout<<-foo<<'\n';
    cout<<foo*(-1)<<'\n';
    cout<<static_cast<int>(-foo)<<'\n';
    cout<<static_cast<int>(foo)*-1<<'\n';
}

的产率:

4294967295
4294967295
4294967295
-1
-1

通过缠绕其最大值(这也应该是理论行为),将无符号无符号或无符号乘以-1溢出。

将size_t传递给 http://en.cppreference.com/w/cpp/container/vector/operator_at,如果偶然std::vector<T>::size_type不是size_t(不太可能,但可能),请在您的向量范围内传递size_t size()应该是安全的并且不会导致UB,因为size_t必须足够大以索引任何大小的数组。