[comp.lang.c] typesafe downward casting

Kai_Henningsen@ms.maus.de (Kai Henningsen) (04/12/91)

DS>>I would maintain ... that a good program generally has few casts and a
DS>>good programming language allows most programs to be written without casts.
DS>
DS>Since C, and for the most part C++ as well, are not strongly typed languages
DS>and rely on casts to allow the programmer to make explicit changes in type,
DS>I would disagree with the above statement. Automatic or built in changes of
DS>type are essentially hidden rules which rely on the programmers intimate
DS>knowledge of the type structure and possibly even an intimate knowledge
DS>of the program  to understand what is really happening.

I think you got something backward there. C uses Casts for two completely
different purposes: one, to convert values (as in (double)1), something other
languages tend to do with explicut library calls (if it's not automatic the
same way as in C), and another, to make the compiler *interpret* the *same*
value different (as in (int *)"blabla").

While there is certainly use for the first variant, the second one is almost
always a sign of bad type design, sometimes by the programmer, sometimes by
the language designer.

In general, such a reinterpretation shouldn't be needed, neither automatic
nor explicit; the only exceptions I can think of in this moment are
* objects being assigned to parent classes (after all, they HAVE the needed
  properties)
* functions that have to manipulate "generic data", such as memory allocation
  or i/o base functions.

DS>of type checking the language provides. Erosion of that type checking
DS>provides more pitfalls into which programmers can fall.

Exactly - and Casts ARE such an erosion.

MfG Kai

torek@elf.ee.lbl.gov (Chris Torek) (04/15/91)

In article <13100@ms.maus.de> Kai_Henningsen@ms.maus.de (Kai Henningsen) writes:
>... C uses Casts for two completely different purposes: one, to convert
>values (as in (double)1) ... and another, to make the compiler *interpret*
>the *same* value different (as in (int *)"blabla").

The latter is a conversion as well---for instance, when sizeof(int) ==
sizeof(long), `int x; (long)x' converts x by very carefully taking each
bit, turning it over twice, and putting it in the same place it came
from.  The result, of course, is just the original value again.

Yes, I am kidding about `turning it over twice'.

Seriously, even casts that do not cause any change in actual bit
pattern are still conversions, and the result of every cast is a value,
not an object.  Many compilers delete identity-conversions too early in
compilation, and wind up permitting assignments that should be
rejected, which makes people think casts are like unions.  Nonetheless,
every cast is a conversion, and every cast produces a new value, even
if the compiler figures out a way to do this using no machine code.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov