Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a compiler inline a virtual function if I use a pointer in a clear situation?

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();
  1. 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?
  2. Suppose that the B has some child classes but these classes haven't its own doSth() function. So compiler should "know" that the only function to call is B::doSth(). I guess it doesn't inline though?
like image 966
somnock Avatar asked Jul 26 '11 20:07

somnock


People also ask

Can you inline a virtual function?

Whenever a virtual function is called using base class reference or pointer it cannot be inlined, but whenever called using the object without reference or pointer of that class, can be inlined because the compiler knows the exact class of the object at compile time.

Can virtual functions are accessed by using object pointer?

Virtual functions are accessible using object pointers. Redefining the virtual function in the derived class is optional, but it needs to be defined in the base class. The function call resolving is done at run-time. You can create a virtual destructor but not a constructor.

Can we create pointer of a class which contains pure virtual function in it?

An abstract class is a class in C++ which have at least one pure virtual function. Abstract class can have normal functions and variables along with a pure virtual function. Abstract class cannot be instantiated, but pointers and references of Abstract class type can be created.

What are the rules to be considered for virtual function?

Rules for Virtual Functions Virtual functions cannot be static. A virtual function can be a friend function of another class. Virtual functions should be accessed using pointer or reference of base class type to achieve runtime polymorphism.


1 Answers

It doesn't matter whether B has any derived classes. In that situation b points to a B 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.

// 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
}
// ...

As can be seen, clang does direct calls to f, both when a points to a A and when it points to a B. GCC does that too.

like image 118
Johannes Schaub - litb Avatar answered Nov 09 '22 03:11

Johannes Schaub - litb