如果我在明确的情况下使用指针,编译器可以内联虚拟函数吗?
我已经读过 内联虚拟函数真的毫无意义吗? 。但我仍然有一些疑问,并没有找到答案。
他们说,如果情况不明确,编译器应该内联虚拟函数。
然而:
只有当编译器拥有实际对象而不是对象的指针或引用时,才会发生这种情况。
那么,如果我有一个从 A
派生的 B
类(包含一个 virtual void doSth()
函数)并且我使用 < code>B* 指针,而不是 A*
:
B* b = new B;
b->doSth();
- 假设
B
没有任何子类。应该调用什么函数(在编译时)是相当明显的。所以内联是可以的。事实是这样吗? - 假设
B
有一些子类,但这些类没有自己的doSth()
函数。因此编译器应该“知道”唯一要调用的函数是B::doSth()
。我猜它没有内联?
I've already read Are inline virtual functions really a non-sense?. But I still have some doubts and found no answer there.
They say that if situation isn't ambiguous, compiler should inline the virtual function.
However:
This can happen only when the compiler has an actual object rather than a pointer or reference to an object.
So what if I have a B
class derived from an A
one (which contains a virtual void doSth()
function) and I use the B*
pointer, not the A*
:
B* b = new B;
b->doSth();
- Suppose that the
B
hasn't any child classes. It's rather obvious (on the compile time) what function should be called. So it's possible to be inlined. Is it in fact? - Suppose that the
B
has some child classes but these classes haven't its owndoSth()
function. So compiler should "know" that the only function to call isB::doSth()
. I guess it doesn't inline though?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
B
是否具有任何派生类并不重要。在这种情况下,b
指向B
对象,以便编译器可以内联调用。当然,任何像样的现代编译器都可以并且将会在您的情况下做到这一点。如果你不使用指针,事情就会变得容易得多。那么这并不是真正的“优化”。只需查看
.
运算符左侧的 AST 节点,您就可以省略虚拟调用,这一事实就变得显而易见。但如果你使用指针,你需要跟踪被指针的动态类型。但现代编译器有能力做到这一点。编辑:一些实验是有序的。
可以看出,当
a
指向A
和指向B 时,clang 都会直接调用
。海湾合作委员会也这样做。f
It doesn't matter whether
B
has any derived classes. In that situationb
points to aB
object so the compiler can inline the call.And surely any decent modern compiler can and will do that in your situation. If you don't use pointers it becomes a whole lot easier. It's not really an "optimization" then. The fact that you can omit a virtual call then becomes obvious by only looking at the AST node at the left side of the
.
-operator. But if you use pointers, you need to track the dynamic type of the pointee. But modern compilers are capable of that.EDIT: Some experiment is in order.
As can be seen, clang does direct calls to
f
, both whena
points to aA
and when it points to aB
. GCC does that too.当 vtable 未针对调用取消引用时,可以内联虚拟成员函数。这可以通过对成员函数进行显式作用域调用来完成。
A virtual member function can be inlined when the vtable is not dereferenced for the call. This can be accomplished by making an explicitly scoped call to the member function.