I take some things for granted and say I will get into details later when needed. Which sometimes can be sane because some subjects don’t have an ending, they get me from one detail to another. And there are situations where I stop at a particular level. It’s the case for static_cast. To simply put it, it turns out I don’t know how it really works.
Because the name includes “static”, I wrongfully assumed it knows, at compile-time, what it’s going to happen to a runtime value. And that it just forcefully and trustfully copies information from one source to another, converting from one type to another. It believes I know what I’m doing and obeys as much as it can.
Another reason for not bothering too much with details is that I never used a static cast for other types than numeric ones. And this simplifies things.
Not long ago I learned that a static cast can have runtime overhead. It was a big surprise until I was reminded of the user-defined conversions and until, of course, I read the documentation.
The simple case
For basic types such as int and float, it’s easier to reason.
float f; auto i = static_cast<int>(f);
would get to:
movss xmm0, DWORD PTR [rbp-4] cvttss2si eax, xmm0 mov DWORD PTR [rbp-8], eax
This means:
-
- copy the
f
variable from the stack into thexmm0
register, - convert from float to integer into the
eax
register, - copy the result onto the stack in the
i
variable.
- copy the
User-defined conversions
When one of the operands is of a user type (eg. a struct), I add a function to intermediate such a conversion because the compiler does not understand how I want the conversion to be performed. Continue reading static_cast runtime overhead