Avi*_*ash 43 c++ stl visual-c++
对于以下类型的代码,我总是得到以下警告.
std::vector v;
for ( int i = 0; i < v.size(); i++) {
}
Run Code Online (Sandbox Code Playgroud)
warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
我明白size()
返回size_t
,只是想知道是否可以安全地忽略此警告,或者我应该创建所有类型的循环变量size_t
Ben*_*igt 48
如果您可能需要INT_MAX
在矢量中保留多个项目,请使用size_t
.在大多数情况下,它并不重要,但我size_t
只是用来使警告消失.
更好的是,使用迭代器:
for( auto it = v.begin(); it != v.end(); ++it )
Run Code Online (Sandbox Code Playgroud)
(如果您的编译器不支持C++ 11,请使用std::vector<whatever>::iterator
代替auto
)
C++ 11也使得选择最佳索引类型变得更容易(如果你在某些计算中使用索引,而不仅仅是为了下标v
):
for( decltype(v.size()) i = 0; i < v.size(); ++i )
Run Code Online (Sandbox Code Playgroud)
Alo*_*ave 17
什么是size_t
?
size_t
对应于语言运算符返回的整数数据类型,sizeof
并在头文件(以及其他)中定义为unsigned integral type
.
它是好投size_t
来int
?
如果您确定大小永远不会超过,则可以使用强制转换INT_MAX
.
如果您正在尝试编写可移植代码,则不安全,因为,
size_t
在64 bit Unix
是64 bits
size_t
在64 bit Windows
为32 bits
因此,如果您将代码从Unix移植到WIndows,如果上面是环境,您将丢失数据.
建议的答案
鉴于警告,建议是使i
的unsigned integral type
甚至更好的使用它作为类型size_t
.
Bil*_*eal 11
这样可以安全地忽略这个警告,或者我应该创建size_t类型的所有循环变量
不,你正在打开一类整数溢出攻击.如果向量大小大于MAX_INT
(攻击者有办法使其发生),您的循环将永远运行,从而导致拒绝服务的可能性.
但从技术上讲,std::vector::size
回报std::vector::size_type
.
您应该为循环计数器变量使用正确的符号.(实际上,对于大多数用途,您希望无符号整数而不是循环的有符号整数)
问题是你混合了两种不同的数据类型.在某些体系结构上,size_t
是32位整数,在其他体系结构上是64位.您的代码应该正确处理两者.
因为size()
返回一个size_t
(不是int),那么它应该是你比较它的数据类型.
std::vector v;
for ( size_t i = 0; i < v.size(); i++) {
}
Run Code Online (Sandbox Code Playgroud)
以下是Bjarne Stroustrup的另一个观点:http: //www.stroustrup.com/bs_faq2.html#simple-program
for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';
Run Code Online (Sandbox Code Playgroud)
是的,我知道我可以声明我是一个vector :: size_type而不是普通的int来安静来自一些超级可疑的编译器的警告,但在这种情况下,我认为这太迂腐和分散注意力.
这是一种权衡.如果您担心v.size()可能超过2,147,483,647,请使用size_t.如果你在循环中使用i不仅仅是查看向量内部,而是关注微妙的有符号/无符号相关错误,请使用int.根据我的经验,后一个问题比前者更普遍.您的经历可能有所不同
另请参阅为什么size_t未签名?.