在C ++中删除分支,无法解释输出后的推理。
PopHi()
采用两个升序排序的向量和到目前为止每个最大的当前索引。它通过递减两者中较大者的索引来“弹出”最大的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??
答案 0 :(得分:3)
idxHiA -= (arrA[idxHiA] >= arrB[idxHiB]);
你在这里改变idxHiA
......
idxHiB -= (!(arrA[idxHiA] >= arrB[idxHiB]));
......在这里咬你。您想使用idxHiA
的旧值,但使用递减的值(可能是非法的BTW)。该位置的元素不再是最大值。
我建议将比较结果存储到一个布尔变量中,以便更清楚地阅读。
PS:我会在汇编程序中检查你的“无分支”版本实际上没有分支。有时,使用分支转换布尔变量的操作。