[英]Will GCC optimize away an inline accessor?
假设我有这门课
class Point
{
inline float x() const { return v[0]; }
inline float y() const { return v[1]; }
inline float z() const { return v[2]; }
float v[3];
};
我这样做:
Point myPoint;
myPoint[0] = 5;
// unrelated code goes here
float myVal = myPoint.x() + 5;
-O2
或-O3
上的 GCC 会通过获取v[0]
优化掉对x()
任何调用吗? IE:
float myVal = myPoint.v[0] + 5;
或者有什么理由说明这是不可能的?
更新:应该提到我确实意识到inline
对编译器来说更像是一个建议,而不是其他任何东西,但无论如何都想知道。
作为一个附加问题,对此类进行模板化是否会对可以进行的优化产生任何影响?
GCC 会优化掉内联访问器吗?
所有优化编译器都会这样做。 与其他优化相比,这是一个微不足道的优化。
或者有什么理由说明这是不可能的?
没有理由使它不可能,但也没有保证。
作为一个附加问题,对此类进行模板化是否会对可以进行的优化产生任何影响?
不是。但是,当然,编译器可能有不同的模板内联阈值。
您可以在此处观察差异: https : //godbolt.org/
假设您有此代码(您的代码无法编译:缺少;
并且Point
没有[]
):
struct Point
{
inline float x() const { return v[0]; }
inline float y() const { return v[1]; }
inline float z() const { return v[2]; }
float v[3];
};
int main() {
Point myPoint;
myPoint.v[0] = 5;
float myVal = myPoint.x() + 5;
return myVal;
}
然后gcc 9.2 发出:
Point::x() const:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
movss xmm0, DWORD PTR [rax]
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
movss xmm0, DWORD PTR .LC0[rip]
movss DWORD PTR [rbp-16], xmm0
lea rax, [rbp-16]
mov rdi, rax
call Point::x() const
movss xmm1, DWORD PTR .LC0[rip]
addss xmm0, xmm1
movss DWORD PTR [rbp-4], xmm0
movss xmm0, DWORD PTR [rbp-4]
cvttss2si eax, xmm0
leave
ret
.LC0:
.long 1084227584
我不太擅长阅读汇编程序,但我将上面的内容与-O3
的输出进行比较就足够令人信服了:
main:
mov eax, 10
ret
生成的代码可能会因上下文而有很大差异,我只是想知道是否有任何根本原因它永远不会或总是会发生。
上面的例子已经反驳了“从不”。 然而,“总是”很难得到。 您得到的保证是生成的代码的行为就像编译器在没有应用优化的情况下翻译了您的代码一样。 除了少数例外,通常不能保证优化。 可以肯定的是,我只会依赖于在现实场景中查看编译器的输出。
它可能会或可能不会被内联。 那里没有保证。 但是,如果您希望它始终内联,请使用[[gnu::always_inline]]
属性。 请参阅此处的文档。 仅当您知道自己在做什么时才使用此属性。 在大多数情况下,最好让编译器决定哪些优化是合适的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.