Standard C does not require a cast for assignments from a (void *) type to
some other pointer type. The "narrowing" is done for you. Since malloc()
returns a `void *', no cast is required.
As has been repeated here before, an explicit cast is discouraged,
because if there is not a prototype in scope, malloc() is assumed to be
a function returning an `int'. Without a prototype in scope, the cast
will hide the fact that malloc() has returned an `int' rather than a
`void *', and your compiler will not have had the opportunity to warn
you about the mistake. If the size of an `int' is not the same size as
a `void *' on your machine, then `bad things will happen'. If it does
happen to work on your machine, then you will become terribly confused
when the identical code does not work on someone else's machine.
If you get a warning about there being no prototype for malloc() in
scope then your code is broken, pure and simple. No amount of casting
will cure it.
This is the reason for advising against casting the result of malloc().
If you cast the result of malloc then *some* compilers will still detect
the error of not including stdlib.h. If you don't cast the result
of malloc then *all* compilers will detect it.