Question

When coding in low level languages like C I find that casting sometimes means 'reinterpret these bytes as if it had always been of this other type' and at other times as 'convert this value intelligently into this other type'.

What is the original meaning of the word and is there any consistency in when to expect a conversion and when to expect a raw reinterpretation?

Was it helpful?

Solution

Casting in C is unique, quite unlike other languages. It is also never intelligent.

Casting in C converts values from one type to another using carefully defined rules. If you really need to know, read the standard. Otherwise the main points are:

  1. Conversion between integer types preserve the value, if possible. If the destination has more bits this is widening and generally safe, but may involve sign extension. If narrower, bits will be lost.
  2. Conversion between pointer types preserves the pointer value, but the results are often undefined, often non-portable and often useful for advanced scenarios.
  3. Conversion between integer types and pointers are OK if the integer is big enough, and preserves the bit pattern (whatever that might happen to mean). If the integer is too small, the result is undefined but not useful. As a rule 'long' is wide enough for 'void *', but no guarantees! Pointers created this way may be invalid, in all kinds of interesting ways.
  4. Conversion between float and integer types are arithmetic conversions as defined by an appropriate library routine (with truncation, not rounding).
  5. You can cast the return value of a function to void. I never have. It does nothing.

Some casts are applied implicitly, and in some of those the compiler will issue a warning. Best to heed the warnings!

The dictionary definition for cast is best ignored, as being unhelpful. Many casts are better described by the terms conversion or coercion, so it's worth knowing those too.

C++ is MUCH more complicated, but you didn't ask that, did you?

OTHER TIPS

This part of the Webster dictionary gives the proper definition:

a : to give a shape to (a substance) by pouring in liquid or plastic form into a mold and letting harden without pressure
b : to form by this process

So, before casting, your "object" (not literally an OOP object) is in a given shape (type). When you re-cast it, that is "pour concrete" around it to make it into a new shape, that is what you do with casting. You have a number as a hexagon-shaped integer, and after casting, you will get a rectangle-shaped string.

It may be useful to separate C casts to two groups:

  1. Numeric casts - convert a number between one representation to another, attempting to keep the value. For example - (int)3.1 would be 3. There are exact rules defining what happens when the exact value can't be kept.

  2. Pointer casts - Keep the memory address, but change the way it's dereferenced. For example, for float x=3.5, *(int *)&x will give 1080033280 - this integer is represented by the same bit pattern that represents the float 3.5.

cast (v): to receive form in a mold

In C++ the various kinds of casts can be made more explicit, with reinterpret_cast meaning "treat these bytes as if they were already this other thing". In C you can make that absolutely explicit by using a union, casting with the (type) operator will attempt to keep the result numerically equivalent, up to loss of precision.

Licensed under: CC-BY-SA with attribution
scroll top