Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inline a virtual function in a method when the object has value semantics

Consider the following code with a template method design pattern:

class A {
    public:
        void templateMethod() {
            doSomething();
        }
    private:
        virtual void doSomething() {
            std::cout << “42\n”;
        }
};
class B : public A {
    private:
        void doSomething() override {
            std::cout << “43\n”;
        }
};

int main() {
    // case 1
    A a; // value semantics
    a.templateMethod(); // knows at compile time that A::doSomething() must be called

    // case 2
    B b; // value semantics
    b.templateMethod(); // knows at compile time that B::doSomething() must be called

    // case 3
    A& a_or_b_ref = runtime_condition() ? a : b;  // ref semantics 
    a_or_b_ref.templateMethod(); // does not know which doSomething() at compile time, a virtual call is needed
    return 0;
}

I am wondering if the compiler is able to inline/unvirtualize the “doSomething()” member function in case 1 and 2. This is possible if it creates 3 different pieces of binary code for templateMethod(): one with no inline, and 2 with either A::doSomething() or B::doSomething() inlined (that must be called respectively in cases 3, 1 and 2)

Do you know if this optimization is required by the standard, or else if any compiler implements it ? I know that I can achive the same kind of effect with a CRT pattern and no virtual, but the intent will be less clear.

like image 554
Bérenger Avatar asked Dec 18 '14 05:12

Bérenger


1 Answers

The standard does not require optimisations in general (occasionally it goes out of its way to allow them); it specifies the outcome and it is up to the compiler to figure out how best to achieve it.

In all three cases I would expect templateMethod to be inlined. The compiler is then free to perform further optimisations; in the first two cases it knows the dynamic type of this and so can generate a non-virtual call for doSomething. (I'd then expect it to inline those calls.)

Have a look at the generated code and see for yourself.

like image 162
Alan Stokes Avatar answered Oct 05 '22 11:10

Alan Stokes