简体   繁体   English

size_t vs int 警告

[英]size_t vs int warning

I am getting following warning always for following type of code.对于以下类型的代码,我总是收到以下警告。

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

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

I understand that size() returns size_t , just wanted to know is this safe to ignore this warning or should I make all my loop variable of type size_t我知道size()返回size_t ,只是想知道忽略此警告是否安全,或者我应该将所有循环变量设为size_t类型

If you might need to hold more than INT_MAX items in your vector, use size_t .如果您可能需要在向量中保存超过INT_MAX个项目,请使用size_t In most cases, it doesn't really matter, but I use size_t just to make the warning go away.在大多数情况下,这并不重要,但我使用size_t只是为了使警告 go 消失。

Better yet, use iterators:更好的是,使用迭代器:

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

(If your compiler doesn't support C++11, use std::vector<whatever>::iterator in place of auto ) (如果您的编译器不支持 C++11,请使用std::vector<whatever>::iterator代替auto

C++11 also makes choosing the best index type easier (in case you use the index in some computation, not just for subscripting v ): C++11 还可以更轻松地选择最佳索引类型(如果您在某些计算中使用索引,而不仅仅是下标v ):

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

What is size_t ?什么是size_t
size_t corresponds to the integral data type returned by the language operator sizeof and is defined in the header file (among others) as an unsigned integral type . size_t对应于语言运算符sizeof返回的整数数据类型,并在 header 文件(以及其他文件)中定义为unsigned integral type

Is it okay to cast size_t to int ?可以将size_t转换为int吗?
You could use a cast if you are sure that size is never going to be > than INT_MAX .如果您确定 size 永远不会大于INT_MAX ,则可以使用强制转换。

If you are trying to write a portable code, it is not safe because, 如果您正在尝试编写可移植代码,这是 不安全的,因为,

size_t in 64 bit Unix is 64 bits 64 bit Unix中的size_t64 bits
size_t in 64 bit Windows is 32 bits 64 bit Windows中的size_t32 bits

So if you port your code from Unix to WIndows and if above are the enviornments you will lose data. 因此,如果您将代码从 Unix 移植到 WIndows 并且如果以上是环境,您将丢失数据。

Suggested Answer建议的答案

Given the caveat, the suggestion is to make i of unsigned integral type or even better use it as type size_t .鉴于警告,建议将i设为unsigned integral type ,甚至更好地将其用作size_t类型。

is this safe to ignore this warning or should I make all my loop variable of type size_t忽略这个警告是否安全,或者我应该将所有循环变量设为 size_t 类型

No. You are opening yourself up to a class of integer overflow attacks.不,您正在接受 class 的 integer 溢出攻击。 If the vector size is greater than MAX_INT (and an attacker has a way of making that happen), your loop will run forever, causing a denial of service possibility.如果向量大小大于MAX_INT (并且攻击者有办法做到这一点),您的循环将永远运行,从而导致拒绝服务的可能性。

Technically, std::vector::size returns std::vector::size_type , though.不过,从技术上讲, std::vector::size返回std::vector::size_type

You should use the right signedness for your loop counter variables.您应该为循环计数器变量使用正确的符号。 (Really, for most uses, you want unsigned integers rather than signed integers for loops anyway) (实际上,对于大多数用途,您需要无符号整数而不是循环的有符号整数)

The problem is that you're mixing two different data types.问题是您混合了两种不同的数据类型。 On some architectures, size_t is a 32-bit integer, on others it's 64-bit.在某些架构上, size_t是 32 位 integer,在其他架构上是 64 位。 Your code should properly handle both.您的代码应该正确处理这两者。

since size() returns a size_t ( not int ), then that should be the datatype you compare it against.由于size()返回一个size_t而不是 int ),那么这应该是您与之比较的数据类型。

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

Here's an alternate view from Bjarne Stroustrup: http://www.stroustrup.com/bs_faq2.html#simple-program这是 Bjarne Stroustrup 的另一个观点: http://www.stroustrup.com/bs_faq2.html#simple-program

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

Yes, I know that I could declare i to be a vector::size_type rather than plain int to quiet warnings from some hyper-suspicious compilers, but in this case,I consider that too pedantic and distracting.是的,我知道我可以将 i 声明为 vector::size_type 而不是普通的 int 来安静地发出一些超可疑编译器的警告,但在这种情况下,我认为这太迂腐和分散注意力。

It's a trade-off.这是一个权衡。 If you're worried that v.size() could go above 2,147,483,647, use size_t.如果您担心 v.size() 可能 go 高于 2,147,483,647,请使用 size_t。 If you're using i inside your loop for more than just looking inside the vector, and you're concerned about subtle signed/unsigned related bugs, use int.如果您在循环中使用 i 不仅仅是查看向量内部,并且您担心微妙的有符号/无符号相关错误,请使用 int。 In my experience, the latter issue is more prevalent than the former.根据我的经验,后一个问题比前一个问题更普遍。 Your experience may differ.您的体验可能会有所不同。

Also see Why is size_t unsigned?另请参阅为什么 size_t 未签名? . .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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