Thank-you for this clear and explicit question, about a topic that seems to generate a lot of opinions. I have run four versions of your code using Eclipse/Microsoft C compiler on a source file named main.c
.
Case 1:
#include<stdlib.h>
int main(){
char *t = malloc(20);
}
Case 1 compiled with no errors and there was no casting of malloc
.
Case 2:
//#include<stdlib.h> <<== stdlib.h commented out!!
int main(){
char *t = malloc(20);
}
Case 2, received the following warning:
..\main.c(14) : warning C4047: 'initializing' : 'char *' differs in levels of indirection from 'int'
The reason for this is that malloc
is defined in <stdlib.h>
, when the prototype for a function is not provided then C assumes that the function is returning an int
, yet t
is a char *
thus the warning.
Case 3:
//#include<stdlib.h> <<== stdlib.h commented out
int main(){
char *t = (char *) malloc(20);
}
This compiled with no errors, but only because the cast statement (char *)
told the compiler that the results of malloc
could indeed be assigned to t
.
Finally, Case 4:
#include<stdlib.h>
int main(){
char *t = (char *) malloc(20);
}
This also ran with no compilation or run-time errors. And Case 4 is the point of many opinions. The cast statement (char *)
in Case 4 can be considered extraneous. However, it does provide information to the human. In this case the C compiler converts a void *
to a char *
just like it would do without the cast!!
Case 4 is cheaper to maintain over the lifetime of the code, in that it lessens the chance that a human will NOT understand the intent of the code.