我只是想知道大多数编译器是否可以进行以下优化
class A
{
virtual void f() { m = 5; }
void g() { f(); }
int m;
};
f()
是一个虚函数,因此不是内联函数。但是,由于g()
的定义很短且可用,编译器可以优化f()
来调用f()
作为内联吗?
答案 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.