GCC 会优化内联访问器吗?

Will GCC optimize away an inline accessor?

假设我有这个class

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 是否会优化掉对 x() 的任何调用而只获取 v[0]?即:

float myVal = myPoint.v[0] + 5;

或者为什么这是不可能的?

更新:应该提到我确实意识到 inline 比其他任何东西都更像是对编译器的建议,但无论如何我都想知道。

作为附加问题,将此模板化 class 会对可以完成的优化产生任何影响吗?

您可以在此处观察差异: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 emits:

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

我不太精通汇编程序,但我认为将上面的内容与 the output with -O3 进行比较就足够有说服力了:

main:
        mov     eax, 10
        ret

The generated code can vary dramatically depending on the context, I just wanted to know if there was any fundamental reasons it could never or would always happen.

上面的例子已经反驳了"never"。 "Always",却难求。您得到的保证是生成的代码的行为就像编译器在没有应用优化的情况下翻译您的代码一样。除了少数例外,通常不能保证优化。可以肯定的是,我只会依赖于查看现实场景中的编译器输出。

它可能内联也可能不内联。那里没有保证。但是,如果您希望它始终内联,请使用 [[gnu::always_inline]] 属性。请参阅文档 here。仅当您知道自己在做什么时才使用此属性。在大多数情况下,最好让编译器决定适合的优化。

Will GCC optimize away an inline accessor?

所有优化编译器都会这样做。与其他优化相比,这是一个微不足道的优化。

Or is there a reason why this is impossible?

没有理由不可能,但也没有保证。

As an additional question, will templating this class have any effect on the optimizations that can be done?

没有。但是,当然,编译器可能有不同的模板内联阈值。