Look at this little snippet:
struct A {
virtual ~A() { }
};
struct B { };
bool fn() {
A *volatile a = new A;
return dynamic_cast<B *>(a);
}
Is the compiler allowed to remove the dynamic_cast
altogether, and transform dynamic_cast
to a simple nullptr;
?
The reason of this question is this answer.
Notes:
Assume that volatile means that the compiler cannot assume anything about a
, because it's volatile. Here's a question why.
The fact that dynamic_cast
may not be allowed to be removed is that there could be a type somewhere in the program, which derives from both A
and B
.
If the dynamic_cast operator succeeds, it returns a pointer that points to the object denoted by arg . If dynamic_cast fails, it returns 0 . You may perform downcasts with the dynamic_cast operator only on polymorphic classes.
dynamic_cast will no longer throw an exception when type-id is an interior pointer to a value type, with the cast failing at runtime. The cast will now return the 0 pointer value instead of throwing.
While typeid + static_cast is faster than dynamic_cast , not having to switch on the runtime type of the object is faster than any of them. Save this answer.
dynamic_cast runs at about 14.4953 nanoseconds. Checking a virtual method and static_cast ing runs at about twice the speed, 6.55936 nanoseconds.
Yes. dynamic_cast
has no observable behavior beyond its return value.
The compiler is aware of the static type pointed to by a
.
So under the as-if rule, the compiler is free to evaluate the dynamic cast at compile time.
In fact:
struct A { virtual ~A() {} };
struct B:A {};
bool foo() {
A* a = new A;
return dynamic_cast<B*>(a);
}
the above dynamic cast statement can also be optimized to return false;
The new
cannot be omitted without whole program optimization as someone could overload the global operator new; once it is proven that no global operator new is overloaded, it could even optimize out the call to new A
, as neither allocating memory by the default operator new
, nor creating an A
nor destroying one has any observable side effects.
Yes, a compiler can omit the call to dynamic_cast
as per as-if rule 1) if and only if it can prove that the only valid result of the call is false
. That's simple.
The tricky part is to prove that the only valid result of dynamic_cast
is false
. You can prove that iff there is no class in your whole program that inherits both from A
and B
.
Now I am not very versed in this part, but I think you can do that when you create the binary and have all the types in your program only if it's an executable (not a library) and only if the program doesn't dynamically link to other libraries.
1) the dynamic_cast
on pointers doesn't have side effect, it doesn't throw
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