Does typecasting consume extra CPU cycles
There are different types of casts. C++ has different types of cast operators for the different types of casts. If we look at it in those terms, ...
static_cast
will usually have a cost if you're converting from one type to another, especially if the target type is a different size than the source type. static_cast
s are sometimes used to cast a pointer from a derived type to a base type. This may also have a cost, especially if the derived class has multiple bases.
reinterpret_cast
will usually not have a direct cost. Loosely speaking, this type of cast doesn't change the value, it just changes how it's interpreted. Note, however, that this may have an indirect cost. If you reinterpret a pointer to an array of bytes as a pointer to an int, then you may pay a cost each time you dereference that pointer unless the pointer is aligned as the platform expects.
const_cast
should not cost anything if you're adding or removing constness, as it's mostly an annotation to the compiler. If you're using it to add or remove a volatile qualifier, then I suppose there may be a performance difference because it would enable or disable certain optimizations.
dynamic_cast
, which is used to cast from a pointer to a base class to a pointer to a derived class, most certainly has a cost, as it must--at a minimum--check if the conversion is appropriate.
When you use a traditional C cast, you're essentially just asking the compiler to choose the more specific type of cast. So to figure out if your C cast has a cost, you need to figure out what type of cast it really is.
I would like to say that "converting between types" is what we should be looking at, not whether there is a cast or not. For example
int a = 10;
float b = a;
will be the same as :
int a = 10;
float b = (float)a;
This also applies to changing the size of a type, e.g.
char c = 'a';
int b = c;
this will "extend c
into an int
size from a single byte [using byte in the C sense, not 8-bit sense]", which will potentially add an extra instruction (or extra clockcycle(s) to the instruction used) above and beyond the datamovement itself.
Note that sometimes these conversions aren't at all obvious. On x86-64, a typical example is using int
instead of unsigned int
for indices in arrays. Since pointers are 64-bit, the index needs to be converted to 64-bit. In the case of an unsigned, that's trivial - just use the 64-bit version of the register the value is already in, since a 32-bit load operation will zero-fill the top part of the register. But if you have an int
, it could be negative. So the compiler will have to use the "sign extend this to 64 bits" instruction. This is typically not an issue where the index is calculated based on a fixed loop and all values are positive, but if you call a function where it is not clear if the parameter is positive or negative, the compiler will definitely have to extend the value. Likewise if a function returns a value that is used as an index.
However, any reasonably competent compiler will not mindlessly add instructions to convert something from its own type to itself (possibly if optimization is turned off, it may do - but minimal optimization should see that "we're converting from type X to type X, that doesn't mean anything, lets take it away").
So, in short, the above example is does not add any extra penalty, but there are certainly cases where "converting data from one type to another does add extra instructions and/or clockcycles to the code".
DL and enjoy Agner Fog's manuals:
http://www.agner.org/optimize/
1. Optimizing software in C++: An optimization guide for Windows, Linux and Mac platforms
It is huge PDF but for start you can check out:
14.7 Don't mix float and double
14.8 Conversions between floating point numbers and integers
It'll consume cycles where it alters the underlying representation. So it will consume cycles if you convert a float
to an int
or vice-versa. Depending on architecture casts such as int
to char
or long long
to int
may or may not consume cycles (but more often than not they will). Casting between pointer types will only consume cycles if there is multiple inheritance involved.