instead of the other one, isn't it? Can somebody give me more technical reason what's the effect of doing this? Sorry, just wanna know more...

Thanx...

Some compilers will give you a warning and some compilers will give you an error. It's a matter of type safety. The compiler checks to make sure that the return type of a function is compatible with the context it's used in. For your example, it will check if void * is compatible with the type of 'curr'. If the type of curr is 'void *', the compiler will let it go. What if 'curr' is a pointer to a different type? The compiler doesn't know if the conversion is legal. That's why it will give you a warning. By adding a manual type cast, you are telling the compiler that the conversion is safe. There really isn't any more depth to this.

The C Standard says:
A pointer to void may be converted to or from a pointer to any incomplete or object
type. A pointer to any incomplete or object type may be converted to a pointer to void
and back again; the result shall compare equal to the original pointer.

There are very very few cases when you need the cast, one such is
when you want the code to compile both as C and C++ and which is
not very often.

And oh! before I forget, the cast shuts the compiler up, so that
even if you did not do a

the
compiler will not complain. And there you've masked an error.
That directive is required because you need to have a prototype
in scope for malloc() and friends. What you have then is Undefined
Behavior.

will compile without problems on a C compiler. C++ does not allow implicit
conversion from void* to any other type. So if you wanted this to get compiled
on a C++ compiler as well you'd have to write something like:

The C committee is to be blamed for this subtle difference in dialect
of the two languages which otherwise has a broad common ground
(this particular usage of void * was borrowed from C++.)

However, have no prejudice and keep in mind it is not required in C but it
is allowed As for C++, the need goes away when you use new
instead. Here's a bit more story:

All examples in K&R2 are valid C++, with the same semantics as in C.

The authors have publicly admitted that this was a mistake on their
part This is from the K&R2 errata:

142: The remark about casting the return value of malloc ("the proper
method is to declare ... then explicitly coerce") needs to be
rewritten. The example is correct and works, but the advice is
debatable in the context of the 1988-1989 ANSI/ISO standards. It's not
necessary (given that coercion of void * to ALMOSTANYTYPE * is
automatic), and possibly harmful if malloc, or a proxy for it, fails
to be declared as returning void *. The explicit cast can cover up an
unintended error. On the other hand, pre-ANSI, the cast was necessary,
and it is in C++ also.

What I've gathered over the years regarding this is:
[0] There was no consensus on which extension to use -- .h, .hpp, .h++ etc
-- whence the idea to drop them.
[1] A compiler implementor is free to make a header's declaration
available in any form it wishes -- not only files. Hence the decision to drop
the '.h' that is so closely tied to the idea of a file on disk.
[2] When namespaces arrived, the C++ committee decided to wrap most
of the standard C library stuff in the 'std' namespace and rename the
headers by prepending a 'c' and dropping the '.h' suffix. The effect is
now to get at library features you use: