C++ 将布尔隐式转换为 int 和算术,删除分支,找不到错误
C++ implicit cast bool to int and arithmetic, removing branches, can't find bug
在C 中删除分支,无法在输出后面解密推理。
PopHi()
采用两个向上排序的ints和到目前为止最大的索引的两个向量。它通过减少两者中较大的索引来"弹出"所有人的最大int。
代码
原始:
void PopHi(vector<int> &arrA, vector<int> &arrB, int &idxHiA, int &idxHiB) {
int hi = max(arrA[idxHiA], arrB[idxHiB]);
if (hi == arrA[idxHiA])
--idxHiA;
else
--idxHiB;
}
Nobranch版本1:
void PopHi(vector<int> &arrA, vector<int> &arrB, int &idxHiA, int &idxHiB) {
idxHiA -= (arrA[idxHiA] > arrB[idxHiB]);
idxHiB -= (!(arrA[idxHiA] > arrB[idxHiB]));
}
NobRanch版本2,因为如果它们相等,我们选择哪一个都不重要:
void PopHi(vector<int> &arrA, vector<int> &arrB, int &idxHiA, int &idxHiB) {
idxHiA -= (arrA[idxHiA] >= arrB[idxHiB]);
idxHiB -= (!(arrA[idxHiA] >= arrB[idxHiB])); // extra paranoia parens
}
这就是我的使用方式:
// compiled with g++ -std=c++11 main.cpp -o run
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> arrA({1, 3, 5});
vector<int> arrB({5});
int idxHiA = 2;
int idxHiB = 0;
cout << idxHiA << ", " << idxHiB << endl;
PopHi(arrA, arrB, idxHiA, idxHiB);
cout << idxHiA << ", " << idxHiB << endl;
return 0;
}
输出
原始:
2, 0
1, 0 // ok
版本1:
2, 0
2, -1 // also ok
版本2:
2, 0
1, -1 // wtf??
idxHiA -= (arrA[idxHiA] >= arrB[idxHiB]);
您正在此处更改idxHiA
...
idxHiB -= (!(arrA[idxHiA] >= arrB[idxHiB]));
...在这里咬你。您想使用idxHiA
的旧值,但正在使用降低的值(可能是非法的BTW)。该位置的元素不再是最大值。
我建议将比较与布尔变量进行比较的结果,这更清楚地读取。
ps:我会在汇编器中检查您的"无分支"版本实际上是没有分支机构的。有时,使用分支进行布尔变量的操作。
相关文章:
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何删除peer if else分支中的冗长句子
- 如何删除 LLVM 中的不规则分支?
- 如何删除分支因子不一致的树,最大为 30,40
- 是否可以使用函数指针数组来删除分支
- 递归树遍历/分支删除的隔离错误
- 如何删除Qtreewidget中的虚线分支
- C++ 将布尔隐式转换为 int 和算术,删除分支,找不到错误
- 如何删除关于负偏移的警告,这些警告在正确的流分支的情况下永远不会发生
- 带有第二个删除器的Shared_ptr链/分支
- 通过按位选择删除分支