Here are some ways in C to convert an arithmetic expression e to a possibly different arithmetic type t.
((t) e)
is powerful and
can therefore be dangerous, because the conversion can succeed even if
neither e nor t happens to have an arithmetic type. For
example, if e is a pointer, ((long int) e)
will do
a conversion even if that was not the intent.
t v = e;
is less
powerful, as it does not convert from pointers. However, it can lose
information and sign, as in for example int v = -0.9;
which
sets v
to zero.
+e
is even less
powerful, as it preserves value (including sign) because it does only
integer promotions. That is, it converts to int
if that can
represent all values of e
’s underlying type, otherwise to
unsigned int
if that can represent all values, and
otherwise it does no conversion.
INT_PROMOTE (e)
is an expression with the same value as
the arithmetic expression e but with e’s type after
any integer promotion. It behaves like +e
.
In the following example, using INT_PROMOTE
pacifies GCC’s
-Wswitch-enum
option, and may help human readers see what is
going on even if they are not expert in C’s integer promotion rules
and might be confused by the simpler switch (+v)
.
enum { A = 1, B, C, D, E } v = ...; switch (INT_PROMOTE (v)) { case A: case C: return true; default: /* Handle all other cases, even cases like v == 0. */ return false; }