Relying on compiler optimization of multiple static cast calls?

Solution 1:

static_cast<T> is not a function.

Depending on the relationship between custom_type* and decltype(obj.get()), and whether a, b or c are virtual, there might be no trace of it in the resulting object code, depending on how the implementation has chosen to implement member function calls.

If the compiler can prove that obj.get() will return the same value each time, and it has no other observable effects, then it might do something equivalent to your second snipped, by the as-if rule.

Solution 2:

In general no. Not based on the information provided in your quesiton.

From the code you posted alone you cannot tell if the two snippets are the same. One reason is that conversion operators can be overloaded and can have side effects. Consider this contrived example (for brevity I omitted the get, but the idea is the same, perform 3 times the same static_cast):

#include <iostream>

struct custom_type {};

struct foo {
    operator custom_type* () {
        std::cout << "x\n";
        return nullptr;
    }
};

int main() {
    foo a;
    auto c = static_cast<custom_type*>(a);
    auto d = static_cast<custom_type*>(a);
    auto e = static_cast<custom_type*>(a);
}

Output is:

x
x
x

Which is different from the output of your "optimized" variant. The compiler may optimize it when it can prove that observable behavior is the same. However, when this is the case then it doesn't matter which variant you write down (because the compiler will know that they are equiavalent).

This is only considering the static_cast, though similarly the call to get might have side effects such that calling it once does not result in same observable behavior than calling it three times. And even if it does, the compiler would need to proove that before it is allowed to perform the desired optimization.