当我遇到涉及检查向量大小的奇怪情况时,我正在谦虚地编码。下面列出了该问题的孤立版本:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> cw = {"org","app","tag"};
int j = -1;
int len = cw.size();
bool a = j>=cw.size();
bool b = j>=len;
std::cout<<"cw.size(): "<<cw.size()<<std::endl;
std::cout<<"len: "<<len<<std::endl;
std::cout<<a<<std::endl;
std::cout<<b<<std::endl;
return 0;
}
同时使用g ++和clang ++(带有-std=c++11
标志)进行编译并运行,结果如下:
cw.size(): 3
len: 3
1
0
为什么j >= cw.size()
的评估结果为true?进行一些实验,发现j的任何负值都会导致这种奇怪的差异。
答案 0 :(得分:2)
这里的陷阱是有符号整数转换,当您将有符号整数值与无符号整数值进行比较时,这些转换将适用。在这种情况下,有符号的值将转换为无符号的值,如果该值为负,则将得到UINT_MAX - val + 1
。因此,-1
将在比较之前转换为非常大的数字。
但是,当您将一个未签名的值分配给一个已签名的值,例如int len = vec.size()
时,该未签名的值将成为一个已签名的值,例如,(未签名)10将得到(已签名)10。而且两个有符号整数之间的比较不会转换两个操作数中的任何一个,并且可以按预期工作。
您可以很简单地模拟它:
int main() {
int j = -1;
bool a = j >= (unsigned int)10; // signed >= unsigned; will convert j to unsigned int, yielding 4294967295
bool b = j >= (signed int)10; // signed >= signed; will not convert j
cout << a << endl << b << endl;
unsigned int j_unsigned = j;
cout << "unsigned_j: " << j_unsigned << endl;
}
输出:
1
0
unsigned_j: 4294967295