利用简短且可定义的虚拟方法进行优化?

时间:2014-04-09 02:34:02

标签: c++ optimization

我只是想知道大多数编译器是否可以进行以下优化

class A
{
    virtual void f() { m = 5; }
    void g() { f(); }
    int m;
};

f()是一个虚函数,因此不是内联函数。但是,由于g()的定义很短且可用,编译器可以优化f()来调用f()作为内联吗?

2 个答案:

答案 0 :(得分:5)

  

编译器可以优化g()来调用f()作为内联,因为f()的定义很短且可用吗?

那令人费解。可以内联g(),以便调用A::g()生成与调用A::f()相同的优化代码。如果从A派生,g()仍然可以内联无论是否在编译时调用运行时类型的变量或通过A*A&到未知运行时类型的对象。

但是,这与f()存在"简短且可用"无关。 - 所以我猜你的意图是询问f()本身是否可以内联:有时候,特别是 - 当编译时知道运行时类型时f()本身也可以内联。

struct B : A { void f() { ... } }
B b;
b.g();  // g() and B::f() may be inlined
A* p = &b;
p->g(); // g() and B::f() may be inlined (latter iff optimiser tracks p addressing a B)
p = opaque_factory();  // definition not known to compiler
p->g(); // equivalent to p->f();, g() inline, f() dispatched virtually / not inline.

void x(A* p) { p->g(); }  // g() may be inlined
x(p); // iff x is inlined, g() and B::f() may be too - per p->g() call above
      // iff x is out-of-line, and compiler doesn't do full-program analysis and find
      //    it's only ever called for a specific runtime type (unlikely if not a
      //    single-translation-unit program), then dispatch to f() can not be inlined
      //    and must be virtual

通过不仅在类定义中声明但实际定义g()(即提供实现),您隐式告诉编译器g()可以是内联的。

g()缺乏开销是Non Virtual Interface idiom的一个原因(虚拟函数非公开并通过非虚拟公共函数访问,允许以后轻松定制基类包装器)添加仪器/日志记录等功能(如果需要)很有吸引力 - 优化版本中没有性能成本,而额外功能尚未添加(<)>

答案 1 :(得分:2)

我认为他们不能。这就是原因:

class B : public A
{
   virtual void f() {}
}

B b;
b.g(); // This must result in B::f() getting called.