Sunday, August 12, 2007

Casting in C

* The cast operator forces the conversion of its SCALAR operand to a specified SCALAR data type, or to void . The operator consists of a type-name, in parentheses, that precedes an expression, as follows:
( type-name ) expression

The type-name can also be an enum specifier, or a typedef name. The type-name can be a structure or union only if it is a pointer. That is, the type-name can be a pointer to a structure or union, but cannot be a structure or union because structures and unions are not scalar types. For example:
     (struct abc *)x /* allowed */
     (struct abc)x /* not allowed */

Cast operations cannot force the conversion of any expression to an array, function, structure, or union. The following example casts the identifier P1 to pointer to array of int:
     (int (*)[10]) p;
This kind of cast operation does not change the contents of P1 ; it only causes the compiler to treat the value of p as a pointer to such an array.
     p + 1; /* Increments by 10*sizeof(int) */

* Cast operators can be used in the following conversions that involve pointers:
- A pointer can be converted to an integral type. A pointer occupies the same amount of storage as objects of type int or long (or their unsigned equivalents). Therefore, a pointer can be converted to any of these integer types and back again without changing its value. No scaling takes place, and the representation of the value does not change. Converting from a pointer to a shorter integer type is similar to converting from an unsigned long type to a shorter integer type; that is, the high-order bits of the pointer are discarded. Converting from a shorter integer type to a pointer is similar to the conversion from a shorter integer type to an object of unsigned long type; that is, the high-order bits of the pointer are filled with copies of the sign bit.
- A pointer to an object or incomplete type can be converted to a pointer to a different object or a different incomplete type. The resulting pointer might not be valid if it is improperly aligned for the type pointed to. For example,
     char c[10];
     int *p = (int *)c[1]; /* misalignment */
It is guaranteed, however, that a pointer to an object of a given alignment can be converted to a pointer to an object of the same alignment or less strict alignment, and back again. The result is equal to the original pointer. (An object of character type has the least strict alignment.) For example,
struct A
{
     struct B;
     int C;
} a, *pa, *pa2;
pa = &a;
struct B *pb;
pb = (struct B *)pa;      /* Allowed and safe. Recall the alignment property of struct */
pa2 = (struct A *)pb;     /* Now pa == pa2 */
- A pointer to a function of one type can be converted to a pointer to a function of another type and back again; the result is equal to the original pointer. If a converted pointer is used to call a function that has a type not compatible with the type of the called function, the behavior is undefined.

Reference: EETime Embedded

No comments: