Home > other >  Relying on compiler optimization of multiple static cast calls?
Relying on compiler optimization of multiple static cast calls?

Time:01-11

I'm working with a code base where I see the following lines of code

  auto a = static_cast<custom_type*>(obj.get())->a();
  auto b = static_cast<custom_type*>(obj.get())->b();
  auto c = static_cast<custom_type*>(obj.get())->c();

Is it reasonable to expect that the compiler would optimize the series of get() and static_cast calls, or would it be better to do something such as:

  auto temp = static_cast<custom_type*>(obj.get());
  auto a = temp->a();
  auto b = temp->b();
  auto c = temp->c();

CodePudding user response:

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.

CodePudding user response:

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).

  •  Tags:  
  • Related