问题描述
我已经看到了一位经验丰富的程序员会做类似的事情:
#include <iostream>
#include <string>
using namespace std;
typedef int BOOL;
BOOL is_max(int a) {
return a&3;
}
class Foo
{
public:
inline Foo() {}
inline ~Foo() {}
int min[3];
int max[3];
};
int main()
{
Foo foo = Foo();
for (int i=0; i<3; i++) {
foo.min[i] = i;
foo.max[i] = i+3;
}
BOOL b = is_max(75); // b==3
// Print out foo.max[1] (which is foo.min[4])
cout << foo.min[1+b] << endl;
}
这是代码中非常昂贵的一部分。因此,我想它的确比使用if条件创建分支要快。由于两个数组(max
和min
)都是int
类型的,并且在类定义中是连续的,因此这应该始终有效。
是否有理由应该避免这种方法?我知道这可能不是代码可读性和可维护性最好的方法(例如,如果有人在错误的位置(即min
和max
之间)在类定义中添加第三个成员)。那时可能会有更好的方法
int[6] extrema;
除此之外,这种方法还会有其他弊端吗?会以某种方式导致过早的终止/分段错误吗?
解决方法
有两个问题,首先,如果b
比1
大,那就是无界访问。
另一个问题是,编译器仅看到foo.max[i] = i+3;
,但在您的代码中没有指示在该循环之后的任何时候都使用max
。因此,从优化器的角度来看,由于访问max
到min
的槽是无效的,因此可以假设循环中的foo.max[i] = i+3;
是无用的,并且可以从理论上对其进行优化。
基于对gcc
的编译输出的简短查看并启用了优化功能,这确实是事实。
因此,即使不会涉及任何未知的填充,并且您可以确定内存布局,也肯定是您绝对不能做的事情。