size_t vs int警告

我总是遵循以下types的代码警告。

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 ,只是想知道这是安全的忽略这个警告,或者我应该让所有我的循环variables的size_ttypes

如果您可能需要在向量中保留多于INT_MAX项目,请使用size_t 。 在大多数情况下,这并不重要,但是我只是使用size_t来使警告消失。

更好的是,使用迭代器:

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

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

C ++ 11也使得select最好的索引types更容易(如果你在一些计算中使用索引,而不仅仅是下标v ):

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

什么是size_t
size_t对应于由语言操作符sizeof返回的整型数据types,并且在头文件(除其他之外)中定义为unsigned integral type

size_tint吗?
如果您确定尺寸不会大于INT_MAX ,则可以使用INT_MAX

如果你正试图编写一个可移植的代码,这是不安全的,因为,

64 bit Unix size_t64 bits
64 bit Windows size_t32 bits

所以,如果你把你的代码从Unix移植到WIndows,如果上面是环境,你将会丢失数据。

build议的答案

给出的警告,build议是使iunsigned integral type或更好地使用它作为size_ttypes。

这是安全的忽略这个警告,或者我应该使所有我的循环variables的size_ttypes

不,你正打开一个整数溢出攻击类。 如果向量大于MAX_INT (攻击者有办法实现这一点),你的循环将永远运行,导致拒绝服务的可能性。

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

你应该为你的循环计数器variables使用正确的符号。 (真的,对于大多数用途,无论如何你都想要无符号整数而不是有符号整数)

问题是你在混合两种不同的数据types。 在一些体系结构中, size_t是一个32位的整数,其他的是64位的。 你的代码应该正确处理两者。

因为size()返回一个size_t不是int ),那么这应该是你比较它的数据types。

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

以下是来自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,而不是plain int,以防止某些超级可疑的编译器发出安静的警告,但在这种情况下,我认为这太过于迂腐和分散注意力。

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

另请参阅为什么size_t无符号? 。