如果我在明确的情况下使用指针,编译器可以内联一个虚函数吗?
Can a compiler inline a virtual function if I use a pointer in a clear situation?
我已经阅读了内联虚函数真的是没有意义的吗?但我还是有些疑惑,没有找到答案。
他们说如果情况不是模糊的,编译器应该内联虚函数。
然而:只有当编译器有一个实际的对象而不是指向对象的指针或引用时,才会发生这种情况。
那么,如果我有一个B
类派生自一个A
(其中包含一个virtual void doSth()
函数),我使用B*
指针,而不是A*
:
B* b = new B;
b->doSth();
- 假设
B
没有子类。(在编译时)应该调用哪个函数是相当明显的。所以有可能是内联的。这是事实吗? - 假设
B
有一些子类,但是这些子类没有自己的doSth()
函数。所以编译器应该"知道"唯一要调用的函数是B::doSth()
。我猜它不是内联的?
B
是否有任何派生类并不重要。在这种情况下,b
指向B
对象,因此编译器可以内联调用。
当然,任何像样的现代编译器都可以并且会在你的情况下这样做。如果你不使用指针,它会变得简单很多。这并不是真正的"优化"。通过查看.
-操作符左侧的AST节点,可以明显地忽略虚调用。但是如果使用指针,则需要跟踪指针的动态类型。但是现在的编译器可以这样做。
编辑:一些实验是有序的。
// main1.cpp
struct A {
virtual void f();
};
struct B : A {
virtual void f();
};
void g() {
A *a = new A;
a->f();
a = new B;
a->f();
}
// clang -O2 -S -emit-llvm -o - main1.cpp | c++filt
// ...
define void @g()() {
%1 = tail call noalias i8* @operator new(unsigned int)(i32 4)
%2 = bitcast i8* %1 to %struct.A*
%3 = bitcast i8* %1 to i32 (...)***
store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @vtable for A, i32 0, i32 2) to i32 (...)**), i32 (...)*** %3, align 4
tail call void @A::f()(%struct.A* %2)
%4 = tail call noalias i8* @operator new(unsigned int)(i32 4)
%5 = bitcast i8* %4 to i32 (...)***
store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @vtable for B, i32 0, i32 2) to i32 (...)**), i32 (...)*** %5, align 4
%tmp = bitcast i8* %4 to %struct.B*
tail call void @B::f()(%struct.B* %tmp)
ret void
}
// ...
可以看到,clang直接调用f
,无论是当a
指向A
还是当它指向B
。GCC也这样做。
当虚值表没有被取消引用时,可以内联虚成员函数。这可以通过显式地对成员函数进行作用域调用来实现。
class A
{
protected:
int a;
public:
inline virtual void Func()
{
a = 0;
}
};
class B : public A
{
public:
inline virtual void Func()
{
a = 1;
}
};
B *obj = new B();
obj->Func(); // Calls B::Func() through vtable;
obj->A::Func(); // Inlines calls to A::Func();
obj->B::Func(); // Inlines calls to B::Func();
相关文章:
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何仅为一个函数添加延迟
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 我需要将多个函数组合为一个函数
- 在C++中声明一个函数时,它需要有函数本身的参数吗
- 如何创建一个函数来计算并返回平均值、最大值和最小值
- 一个函数,用于查找字符串1包含字符串2 c++的次数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 编写一个函数以使用 n 百分比的 CPU 使用率
- 将 N-arg 函数包装到另一个函数中
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- C++从另一个函数退出函数
- 编写一个函数来删除单链表中的节点(尾部除外),仅授予对该节点的访问权限
- 视觉我希望一个函数在另一个函数C++中进行计算
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 在另一个函数 (c++) 中调用变量
- 如何在另一个函数中使用返回值作为参数?
- 如何包装一个函数以适应另一个函数的所需类型
- 创建一个函数的 Python 绑定,返回指向带有 boost 的向量的指针