cast operator

Performs explicit type conversion

Syntax

( type-name ) expression

where

type-name - either the type void or any scalar type
expression - any expression of scalar type (unless type-name is void, in which case it can be anything)

Explanation

If type-name is void, then expression is evaluated for its side-effects and its returned value is discarded, same as when expression is used on its own, as an expression statement.

Otherwise, if type-name is exactly the type of expression, nothing is done (except that if expression has floating type and is represented with greater range and precision than its type indicates -- see below)

Otherwise, the value of expression is converted to the type named by type-name, as follows:

Every implicit conversion as if by assignment is allowed.

In addition to the implicit conversions, the following conversions are allowed:

In any case (both when executing an implicit conversion and in the same-type cast), if expression and type-name are floating types and expression is represented with greater range and precision than its type indicates (see FLT_EVAL_METHOD), the range and precision are stripped off to match the target type.

The value category of the cast expression is always non-lvalue.

Notes

Because const, volatile, restrict, and _Atomic qualifiers have effect on lvalues only, a cast to a cvr-qualified or atomic type is exactly equivalent to the cast to the corresponding unqualified type.

The cast to void is sometimes useful to silence compiler warnings about unused results.

The conversions not listed here are not allowed. In particular,

If the implementation provides intptr_t and/or uintptr_t, then a cast from a pointer to an object type (including cv void) to these types is always well-defined. However, this is not guaranteed for a function pointer.

(since C99)

Note that conversions between function pointers and object pointers are accepted as extensions by many compilers, and expected by some usages of POSIX dlsym() function.

Example

#include <stdio.h>
 
int main(void)
{
    // examining object representation is a legitimate use of cast
    double d = 3.14;
    printf("The double %.2f (%a) is: ", d, d);
    for (size_t n = 0; n < sizeof d; ++n)
        printf("0x%02x ", ((unsigned char*)&d)[n]);
 
    // edge cases
    struct S { int x; } s;
//    (struct S)s; // error; not a scalar type
                   // even though casting to the same type does nothing
    (void)s; // okay to cast any type to void
}

Possible output:

The double 3.14 (0x1.91eb851eb851fp+1) is: 0x1f 0x85 0xeb 0x51 0xb8 0x1e 0x09 0x40

References

See also

C++ documentation for explicit type conversion

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/cast