I wrote this short program to see how devirtualization would work. The compiler should be able to deduce the correct type:
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public:
void foo() { cout << "Base::foo" << endl; }
virtual void bar() { cout << "Base::bar" << endl; }
virtual ~Base() = default;
};
class Child : public Base
{
public:
void foo() { cout << "Child::foo" << endl; }
void bar() { cout << "Child::bar" << endl; }
};
int main()
{
Base* obj = new Child;
obj->foo();
obj->bar();
delete obj;
}
Compiled with -O2 -std=c++11
using gcc 5.3 and clang 3.7 via https://gcc.godbolt.org/.
What turned out is that neither compiler was able to optimize everything - gcc inlines foo()
and makes virtual call to bar()
while clang makes call to foo()
and devirtualizes and inlines call to bar()
.
Meanwhile, if instead I call obj->bar();
and then obj->foo();
, the compilers have no problem in optimizing - clang inlines both calls and gcc makes normal call to bar()
instead of virtual one and inlines foo()
.
Can anyone explain this behavior?
cout
is too expensive compared to the overhead of the function call. If you replace it with something simpler, e.g. an assigment to a member, it gets inlined. – Lanctotendl
s;cout
is well and truly flushed! (use` '\n'` when all you need is to end a line;endl
does a great deal more, none of which is needed ehre) – Analyst