I've been trying to switch to the habit of adding the cast, but I find that
I keep forgetting!
Why? malloc returns a pointer to void - and that is a generic pointer
compatibel to any pointer to object. No cast needed.
There is a rule you should learn: never ever cast except you KNOWs
exactly WHY you must cast. However when you knows not exactly why but
you means you must cast then use a good book, the clc FAQ, or this
group to get more information. Be sure most when not always you'll end
up with 'no cast needed'.
So, by itself, this rule has less worth than a rule which says ``it is poor
practice to make some kind of mistake in your use of malloc'', because
it's essentially a rule which says ``it is poor practice to do something that
is often correct, and even considered a good idiom by some C programmers,
some of whom are experts, and for the violation of which there is no diagnostic
support in the standard language''.
Uh, oh, there is enough diagnostic support - but it is on you to set
the warning level right. Yes, sometimes the compiler will give you a
diagnostic you'll not accept - but that's your fault. It may look like
an orakel but there is no rule that requires that the compiler should
NOT play the role of an orakel.
But what /is/ poor practice is designing a programming language feature which
allows you to request dangerous conversions without having to provide a written
token that marks the places in the program where these conversions
are happening. You simply use the assignment operator between two expressions,
the same way like you could do in a typeless language between /any/ two
expressions. (E.g. a predecessor of C, like BCPL).
In question you would use lint until it says that the source is
errorfree before you start to compile. lint is known as the
errorchecker, the compiler has only to compile and will whine only
when it falls in holes.
The void and void * types come from C++ which has a better rules for them.
It doesn't have the implicit conversion from void * to any object type,
and C++ doesn't have the silly (void) hack. (Someone should have had the
balls to uproot non-prototype declartions from C back in in 1989: boldly
removing something from a standard doesn't mean compilers can't continue to
support it).
Oh, void* is not compatible to any object type! It is only compatible
to any pointer type, except function pointer. And yes, it is much
better than the old plain char* as it explicity declarees that it is
not simply a char* but a pointer with unknow type.
C once had malloc which returned char *. There was nothing wrong with this; it
did not have to change. If anywhere at all, the void * type should have only
been used in the free and realloc functions for passing pointers down.
Oh, there is a big difference between char* and void*. A void* is
mostenly not simple a char* and a char* is not a void* even as the
converation can be done without cast.
So, the thing to do is to eliminate the use of the void * type from your C
programs, at least in situations where it will likely be converted to another
type.
In contrary, learn how to use void* and what makes the difference to
char*.
I recommend that interfaces which accept a generic pointer-to-anything continue
to be written to accept void * arguments, but when those pointers are returned,
they should be returned as unsigned char *.
No, because char* is not identical with void*, they are different
types with different meaning even as they may internal binary
identical.
void* = a pointer pointing to an object of unknown type and size.
char* = a pointer to either an array of chars or a single char.
by that: there are 3 different char*. The old days without void* are
gone - and that is good!
Rationale: it is correct and sometimes useful to be able to treat any
object as an array of bytes (unsigned char *). If we don't know what a
pointer points to, but we do know that it points to an object, then
it's okay for that pointer to be a pointer to unsigned char *. We can
safely dereference that pointer to access a byte. Functions that call
malloc only to obtain a block of bytes should not have to do the cast
since any object already /is/ a block of bytes.
No. char* is either a pointer to a single char or an array of chars or
a string. C does not distinguish between the 3 different object type.
If the object is to be used as some other type, even as a char * string, then a
cast will be required. So, you don't need your rule 10: just design the API so
that code won't compile without the cast.
No, that is the charm of C. void* is compatible to any other pointer
type without conversation - and that is fine. Use void* when the type
of the object pointing to doesn't matter, use char* when the object
the pointer points to is either a single char, an array of chars or a
string. Use another type when the pointer points to another type.
--
Tschau/Bye
Herbert
Visit
http://www.ecomstation.de the home of german eComStation
eComStation 1.2R Deutsch ist da!