I was just reading about the bad practice of casting the return value of malloc
. If I understood correctly, it is absolutely legal to leave the cast as it is do
Basically you need to cast arguments to functions that expect a different parameter than their prototype claims.
For example, isalpha() has a prototype with an int
argument, but really expects an unsigned char
.
char *p;
if ((*p != EOF) && isalpha((unsigned char)*p) /* cast needed */
{
/* ... */
}
And, you need to be extra careful with functions that accept a variable number of arguments, eg:
long big;
printf("%d\n", (int)big);
Edit
The compiler cannot convert the arguments of variadic functions to the proper type, because there is no type information available in the prototype itself. Consider a printf()-like function
int my_printf(const char *fmt, ...);
As far as the compiler is aware, you can pass values of all kinds of types in the "..." argument, and you must make sure the arguments match what the function expects. For example, let's say the my_printf()
function accepts a value of type time_t
with a corresponding "%t" specifier in the format string.
my_printf("UNIX Epoch: %t.\n", 0); /* here, 0 is an int value */
my_printf("UNIX Epoch: %t.\n", (time_t)0); /* and here it is a time_t */
My compiler does not want to make this fail! Apparently it (and the one at codepad too) passes 8 bytes for each argument in "..."
Using a prototype without "..." ( int my_printf(const char *fmt, time_t data);
), the compiler would automagically convert the first 0 to the right type.
Note: some compilers (gcc included) will validate the arguments against the format string for printf()
if the format string is a literal string