[英]size_t vs int warning
对于以下类型的代码,我总是收到以下警告。
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
类型
如果您可能需要在向量中保存超过INT_MAX
个项目,请使用size_t
。 在大多数情况下,这并不重要,但我使用size_t
只是为了使警告 go 消失。
更好的是,使用迭代器:
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 )
什么是size_t
?
size_t
对应于语言运算符sizeof
返回的整数数据类型,并在 header 文件(以及其他文件)中定义为unsigned integral type
。
可以将size_t
转换为int
吗?
如果您确定 size 永远不会大于INT_MAX
,则可以使用强制转换。
如果您正在尝试编写可移植代码,这是
不安全的,因为,
64 bit Unix
中的size_t
是64 bits
64 bit Windows
中的size_t
是32 bits
因此,如果您将代码从 Unix 移植到 WIndows 并且如果以上是环境,您将丢失数据。
建议的答案
鉴于警告,建议将i
设为unsigned integral type
,甚至更好地将其用作size_t
类型。
忽略这个警告是否安全,或者我应该将所有循环变量设为 size_t 类型
不,您正在接受 class 的 integer 溢出攻击。 如果向量大小大于MAX_INT
(并且攻击者有办法做到这一点),您的循环将永远运行,从而导致拒绝服务的可能性。
不过,从技术上讲, std::vector::size
返回std::vector::size_type
。
您应该为循环计数器变量使用正确的符号。 (实际上,对于大多数用途,您需要无符号整数而不是循环的有符号整数)
问题是您混合了两种不同的数据类型。 在某些架构上, size_t
是 32 位 integer,在其他架构上是 64 位。 您的代码应该正确处理这两者。
由于size()
返回一个size_t
(而不是 int ),那么这应该是您与之比较的数据类型。
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';
是的,我知道我可以将 i 声明为 vector::size_type 而不是普通的 int 来安静地发出一些超可疑编译器的警告,但在这种情况下,我认为这太迂腐和分散注意力。
这是一个权衡。 如果您担心 v.size() 可能 go 高于 2,147,483,647,请使用 size_t。 如果您在循环中使用 i 不仅仅是查看向量内部,并且您担心微妙的有符号/无符号相关错误,请使用 int。 根据我的经验,后一个问题比前一个问题更普遍。 您的体验可能会有所不同。
另请参阅为什么 size_t 未签名? .
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.