Casts are generally undesirable, but there are several situations where a cast legitimately comes in handy:
Conversion of one type's range to another's, as in the argument to the
isupper ((unsigned char) c)
Conversion of an integer to a floating-point type for use in arithmetic. (Sure, you can assign it to a variable or multiply it by 1.0, but a cast can sometimes clarify what you're doing.)
Converting a pointer to the first member of a structure to a pointer to the structure, or a pointer to a member of a union to a pointer to the union.
Converting an lvalue to an rvalue for use in macros that can be used for access to objects but should not be used to modify those objects. (The unary plus operator is an alternative.)
Casting between different pointer-to-character types for, e.g., passing a unsigned char array to
strcpy(). (You can avoid it by using a
void *pointer variable as an intermediary, but that's hardly an improvement.)
Silencing compiler warnings about `comparing signed and unsigned types' ;-(
Passing an argument to a varargs function when the corresponding parameter is of an incompatible type, and especially for passing null pointers to varargs functions.