I was very surprised when watching the code generated by visual c++ (VS2017 RC) to see dynamic branching (virtual call) in simple cases.
So I tried the following code with the compiler explorer:
struct Base
{
virtual void foo() = 0;
};
struct Impl : Base
{
void foo() override;
};
Impl g_impl;
void globalCall()
{
g_impl.foo();
}
void localCall()
{
Impl i;
i.foo();
}
void tempCall()
{
Impl().foo(); // dynamic branching generated!
}
struct Class
{
void memberCall();
Impl impl;
};
void Class::memberCall()
{
impl.foo(); // dynamic branching generated!
}
Compiler explorer link: https://godbolt.org/g/RmUku2
With the temporary and the member cases, it looks like no devirtualization occurs. So is it a compiler quality of implementation issue, or is there technical valid reasons for such result?
Just missed cases for devirtualization. It has been like this since the first version in which devirtualization was supported, namely VS 2013. The other compilers gcc, icc, and clang perform devirtualization in all the cases. In general, it is better to explicitly specify final
rather than relying on the compiler to pedantically perform devirtualization. Marking Impl.foo
with final
enables the optimization in all the cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With