Visual C ++: no devirtualization in obvious cases?

I was very surprised to observe 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

In temporary and membership cases, it does not seem to be devirtualization. Is this the quality of the compiler’s execution, or are there justified reasons for such a result?

+6
source share
1 answer

Just missed cases for devirtualization. This was because the first version that supported devirtualization, namely VS 2013. Other gcc, icc, and clang compilers perform devirtualization in all 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 allows optimization in all cases.

+1
source

Source: https://habr.com/ru/post/1014571/


All Articles