在下面声明的C++
如果我在使用gcc编译器(版本5.4)并开启优化(即
请注意,我使用Compiler Explorer来确定编译器生成的内容,并且下面给出了gcc版本5.4的汇编输出。clang编译器也会给出类似的结果。还要注意,如果我使用gcc的编译器属性手动标记
vector
类中,norm
成员函数被标记为const
,并且(据我所知)不包含任何副作用。template <unsigned int N>
struct vector {
double v[N];
double norm() const {
double ret = 0;
for (int i=0; i<N; ++i) {
ret += v[i]*v[i];
}
return ret;
}
};
double test(const vector<100>& x) {
return x.norm() + x.norm();
}
如果我在使用gcc编译器(版本5.4)并开启优化(即
-O3
)的情况下多次调用vector
的const
实例上的norm
函数(参见上面的test
函数),则编译器会内联norm
,但仍会多次计算norm
的结果,尽管结果不应该改变。为什么编译器不能优化第二次对norm
的调用,只计算一次结果?这个答案似乎表明,如果编译器确定norm
函数没有任何副作用,那么编译器应该执行此优化。为什么在这种情况下不会发生这种情况?请注意,我使用Compiler Explorer来确定编译器生成的内容,并且下面给出了gcc版本5.4的汇编输出。clang编译器也会给出类似的结果。还要注意,如果我使用gcc的编译器属性手动标记
norm
为const函数,使用__attribute__((const))
,则第二次调用会被优化掉,这正是我想要的,但我的问题是,为什么gcc(和clang)不会自动执行此操作,因为norm
的定义是可用的?test(vector<100u>&):
pxor xmm2, xmm2
lea rdx, [rdi+800]
mov rax, rdi
.L2:
movsd xmm1, QWORD PTR [rax]
add rax, 8
cmp rdx, rax
mulsd xmm1, xmm1
addsd xmm2, xmm1
jne .L2
pxor xmm0, xmm0
.L3:
movsd xmm1, QWORD PTR [rdi]
add rdi, 8
cmp rdx, rdi
mulsd xmm1, xmm1
addsd xmm0, xmm1
jne .L3
addsd xmm0, xmm2
ret