Han said:
The OP should bear in mind that the above statement is one of those
dogmatic, religious statements on comp.lang.c. To be sure, it's a true
statement as it stands, but the devil is in the details.
The only thing you can take away is that "the cast is unnecessary". That's
it. But keep in mind that most whitespace in C code is also unnecessary.
So it's up to you whether you want to use the cast as a matter of style.
[...]
Unnecessary whitespace doesn't cause the compiler to be less-restrictive
about the code it accepts, while unnecessary casts do.
A cast reduces
restrictions placed on the expression being cast.
That is generally true, but not in this case.
A (type *) cast added to a void * expression increases the restriction,
because unlike the original expression, the augmented expression now no longer
be assigned to an lvalue of arbitrary pointer-to-object type.
So if you put a cast and
then put the wrong expression on the right, or the expression later gets
That would be the case if the void * type hole did not exist.
But the hole being what it is you have to consider this case:
If you put a void * on the right, and there is no cast, you can put a pointer
to any object type on the left, with no diagnostic.
The behavior of void * in C is as if it automatically generated a cast
to the left hand side! If you add your own cast, then you plug this
behavior by forcing a particular type.
// hole in type system:
A a_obj;
A *a = &a_obj;
void *v = a;
B *b = v; // pun!
C *c = v; // pun!
D *d = v; // pun!
changed to be wrong, you're less-likely to have that diagnosed by the
compiler. Thus, you should cast only when necessary.
That's good advice---in a language which doesn't have a type hole that allows
an unsafe conversion! Because in that language, the pointer conversion
situations in which casts are unnecessary are type-safe, and do not require the
documentation of a cast.
The advice needs to have an exception: don't write casts that are not required,
except in situations where the lack of a requirement for a cast is a gaping
hole in the type system!
This is one reason
C++ provides several less-powerful casts, so that one can avoid turning
off so many restrictions, as a C-style cast does.
Note that those less powerful casts are a refinement which came years after C++
banished the implicit conversion from void *.
This is a situation where a diagnostic /should/ be necessary. And that's
the rationale for writing the cast anyway.
The reason that diagnostic is required in a conversion is to alert the
programmers to change the code somehow, or just add a cast if the conversion
looks safe.
The cast, should it be added, is then a visible record in the program text
which makes it obvious that a suspicious conversion is going on.
If you don't ever write casts which are not necessary, but the language has
holes that allow for unsafe conversions without casts, then you may end up with
places in the program where unsafe conversions are occuring inconspicuously.
Let me pose this question to you: suppose that C simply allowed all pointer
conversions to be written, regardless of type, without any diagnostics being
required. Would you then write (A *) to (B *) conversions without a cast, just
because it's unecessary?