c++ - 为什么这个 stl 函数调用会导致不正确的布尔评估?
问题描述
当我遇到一个涉及检查向量大小的奇怪情况时,我正在谦虚地编码。下面列出了该问题的一个独立版本:
#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()
评估为真?稍微试验一下 j 的任何负值都会导致这种奇怪的差异。
解决方案
这里的陷阱是有符号整数转换,当您将有符号整数值与无符号整数值进行比较时会应用。在这种情况下,有符号值将被转换为无符号值,如果值为负,它将得到UINT_MAX - val + 1
. 所以-1
在比较之前会转换成一个很大的数。
但是,当您将无符号值分配给有符号值时,例如int len = vec.size()
,那么无符号值将变为有符号值,例如 (unsigned)10 将得到 (signed)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
推荐阅读
- r - 以编程方式将值发送到过滤器的 tidyeval 方式
- node.js - 节点js上的Multer sftp文件上传问题
- amazon-web-services - 我们可以使用 AWS Spot 实例来保证挖矿利润吗?
- kernel-module - 内核模块重启linux
- php - 无法向另一个 php 网站发出带有文件的 POST 请求
- php - json_encode 值的条件存储在数据库中
- mfc - MFC 中的虚拟组合框
- swift - 如何修复 Swift 对双打的不准确调试描述?
- vba - 我怎样才能为按键事件制作一个子?
- javascript - 来自用户 Angular 的嵌套数据