繁体   English   中英

size_t vs int 警告

[英]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_t64 bits
64 bit Windows中的size_t32 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM