size_t vs int警告

时间:2011-07-05 04:47:39

标签: c++ visual-c++ stl

对于以下类型的代码,我总是会收到以下警告。

std::vector v;
for ( int i = 0; i < v.size(); i++) {
}

warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data

我理解size()返回size_t,只是想知道忽略此警告是否安全,或者我应该创建size_t类型的所有循环变量

5 个答案:

答案 0 :(得分:47)

如果您可能需要在矢量中保留超过INT_MAX个项目,请使用size_t。在大多数情况下,它并不重要,但我使用size_t只是为了让警告消失。

更好的是,使用迭代器:

for( auto it = v.begin(); it != v.end(); ++it )

(如果您的编译器不支持C ++ 11,请使用std::vector<whatever>::iterator代替auto

C ++ 11还可以更轻松地选择最佳索引类型(如果您在某些计算中使用索引,而不仅仅是订阅v):

for( decltype(v.size()) i = 0; i < v.size(); ++i )

答案 1 :(得分:18)

什么是size_t
size_t对应于语言运算符sizeof返回的整数数据类型,并在头文件(以及其他)中定义为unsigned integral type

是否可以将size_t投放到int
如果您确定尺寸永远不会是>,则可以使用演员表。比INT_MAX

如果您正在尝试编写可移植代码,则安全,因为

size_t中的{p> 64 bit Unix64 bits size_t中的64 bit Windows32 bits

因此,如果您将代码从Unix移植到WIndows,如果上面是环境,您将丢失数据。

建议的答案

考虑到警告,建议是i unsigned integral type,或者更好地将其用作size_t类型。

答案 2 :(得分:11)

  

可以安全地忽略此警告,或者我应该创建size_t

类型的所有循环变量

没有。你正在打开一类整数溢出攻击。如果向量大小大于MAX_INT(并且攻击者有办法使这种情况发生),您的循环将永远运行,从而导致拒绝服务。

从技术上讲,std::vector::size会返回std::vector::size_type

您应该为循环计数器变量使用正确的符号。 (实际上,对于大多数用途,无论如何都需要无符号整数而不是有符号整数)

答案 3 :(得分:5)

问题在于您混合了两种不同的数据类型。在某些体系结构中,size_t是32位整数,而其他体系结构是64位。您的代码应该正确处理两者。

因为size()返回size_t not int ),那么这应该是您与之比较的数据类型。

std::vector v;
for ( size_t i = 0; i < v.size(); i++) {
}

答案 4 :(得分:5)

以下是Bjarne Stroustrup的另一个观点: http://www.stroustrup.com/bs_faq2.html#simple-program

for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';
  

是的,我知道我可以声明我是一个vector :: size_type   而不是简单的int来安静一些超级可疑的警告   编译器,但在这种情况下,我认为这太迂腐了   分心。

这是一种权衡。如果您担心v.size()可能超过2,147,483,647,请使用size_t。如果你在循环中使用i不仅仅是查看向量内部,而是关注微妙的有符号/无符号相关错误,请使用int。根据我的经验,后一个问题比前者更普遍。您的经历可能会有所不同。

另见Why is size_t unsigned?