CPP‐Type Conversion - rFronteddu/general_wiki GitHub Wiki
The process of converting data from one type to another type is called type conversion. When the compiler does type conversion on our behalf without us explicitly asking, we call this implicit type conversion. The type conversion process does not modify the value (or object) supplying the data to be converted. Instead, the conversion process uses that data as input, and produces the converted result. Some advanced type conversions (e.g. those involving const_cast or reinterpret_cast) do not return temporary objects, but instead reinterpret the type of an existing value or object. Some type conversions (such as a char to an int) always preserve the value being converted, whereas others (such as double to int) may result in the value being changed during conversion. Unsafe implicit conversions will typically either generate a compiler warning, or (in the case of brace initialization) an error.
C++ supports a second method of type conversion, called explicit type conversion. Explicit type conversion allow us (the programmer) to explicitly tell the compiler to convert a value from one type to another type, and that we take full responsibility for the result of that conversion. If such a conversion results in the loss of value, the compiler will not warn us.
static_cast<new_type>(expression)
#include <iostream>
void print(int x)
{
std::cout << x << '\n';
}
int main()
{
print( static_cast<int>(5.5) ); // explicitly convert double value 5.5 to an int
return 0;
}
Because we’re now explicitly requesting that double value 5.5 be converted to an int value, the compiler will not generate a warning about a possible loss of data upon compilation.
Signed integral values can be converted to unsigned integral values, and vice-versa, using a static cast.
If the value being converted can be represented in the destination type, the converted value will remain unchanged
If the value being converted cannot be represented in the destination type:
- If the destination type is unsigned, the value will be modulo wrapped. We cover modulo wrapping in lesson.
- If the destination type is signed, the value is implementation-defined prior to C++20, and will be modulo wrapped as of C++20.
#include <iostream>
int main()
{
int s { -1 };
std::cout << static_cast<unsigned int>(s) << '\n'; // prints 4294967295
unsigned int u { 4294967295 }; // largest 32-bit unsigned int
std::cout << static_cast<int>(u) << '\n'; // implementation-defined prior to C++20, -1 as of C++20
return 0;
}
Signed int value -1 cannot be represented as an unsigned int. The result modulo wraps to unsigned int value 4294967295. Unsigned int value 4294967295 cannot be represented as a signed int. Prior to C++20, the result is implementation defined (but will probably be -1). As of C++20, the result will modulo wrap to -1.