cppannotations/annotations/yo/first/staticcast.yo
2017-01-24 16:00:11 +01:00

85 lines
3.7 KiB
Text

The hi(static_cast)tt(static_cast<type>(expression)) is used to convert
`conceptually comparable or related types' to each other. Here as well as in
other bf(C++) style casts tt(type) is the type to which the type of
tt(expression) should be cast.
Here are some examples of situations where the tt(static_cast) can (or should)
be used:
itemization(
it() When converting an tt(int) to a tt(double). nl()
This happens, for example when the quotient of two tt(int) values must be
computed without losing the fraction part of the division. The tt(sqrt)
function called in the following fragment returns 2:
verb(
int x = 19;
int y = 4;
sqrt(x / y);
)
whereas it returns 2.179 when a tt(static_cast) is used, as in:
verb(
sqrt(static_cast<double>(x) / y);
)
The important point to notice here is that a tt(static_cast) is allowed to
change the representation of its tt(expression) into the representation that's
used by the destination type.
Also note that the division is put outside of the cast expression. If the
division is performed within the cast's tt(expression) (as in
tt(static_cast<double>(x / y))) an emi(integer division) has already been
performed em(before) the cast has had a chance to convert the type of an
operand to tt(double).
it() When converting tt(enum) values to tt(int) values (in any
direction). nl()
Here the two types use identical representations, but different
semantics. Assigning an ordinary tt(enum) value to an tt(int) doesn't require
a cast, but when the enum is a em(strongly typed enum) a cast em(is)
required. Conversely, a tt(static_cast) is required when assigning an tt(int)
value to a variable of some enum type. Here is an example:
verb(
enum class Enum
{
VALUE
};
cout << static_cast<int>(Enum::VALUE); // show the numeric value
)
it() When converting related pointers to each other.nl()
The tt(static_cast) is used in the context of class inheritance
(cf. chapter ref(INHERITANCE)) to convert a pointer to a so-called `derived
class' to a pointer to its `base class'. It cannot be used for casting
unrelated types to each other (e.g., a tt(static_cast) can+em(not) be used to
cast a pointer to a tt(short) to a pointer to an tt(int)).
A tt(void *) is a em(generic pointer). It is frequently used by
functions in the bf(C) library (e.g., bf(memcpy)(3)). Since it is the generic
pointer it is related to any other pointer, and a tt(static_cast) should be
used to convert a tt(void *) to an intended destination pointer. This is a
somewhat awkward left-over from bf(C), which should probably only be used in
that context. Here is an example:
The tt(qsort) function from the bf(C) library expects a pointer to a
(comparison) function having two tt(void const *) parameters. In fact, these
parameters point to data elements of the array to be sorted, and so the
comparison function must cast the tt(void const *) parameters to pointers to
the elements of the array to be sorted. So, if the array is an tt(int array[])
and the compare function's parameters are tt(void const *p1) and tt(void const
*p2) then the compare function obtains the address of the tt(int) pointed
to by tt(p1) by using:
verb(
static_cast<int const *>(p1);
)
it() When undoing or introducing the signed-modifier of an tt(int)-typed
variable (remember that a tt(static_cast) is allowed to change the
expression's representation!). nl()
Here is an example: the bf(C) function tt(tolower) requires an tt(int)
representing the value of an tt(unsigned char). But tt(char) by default is a
signed type. To call tt(tolower) using an available tt(char ch) we should use:
verb( tolower(static_cast<unsigned char>(ch)))
)