1. to cast an actor for a role based on stereotype
  2. pigeonholed based on past roles.
  3. when roles are written or cast so that a specific actor need not act in order to play the role. E.g.: Keanu Reeves as himself
In programming, making one type treated as another.

char *foo = (char *) malloc( len );: the bold part casts the void pointer malloc return to a character pointer.

I was just watching a Seinfeld rerun, and Kramer said "I'm being typecast!", and as a programmer I thought, "wtf?". :)

To convert from one type to another in C and other programming languages. To cast to a new type, use the new type surrounded in brackets before the old value. eg int foo = (int)3.33333; //foo = 3

In C++, casts can be overloaded, for instance to make a class return a rounded up float member when cast to an integer, use a type conversion operator such as this:

operator int() { return my_float + 0.5; }

See also contexts in Perl.

Most modern high-level programming languages maintain some degree of information about the data they manipulate. One important piece of information is the type of any given value used by the program. By type, I mean information pertaining to how that particular data is stored and what can be done to it. For example, most languages support at least an understanding of the difference between "integer" types and "string" types. This information allows error-checking by the compiler that can reduce many silly programmer errors, like attempting to treat a string as an integer or vice versa: errors that wouldn't be caught if they were made in, say, machine language.

Sometimes, though, the language is wrong, and the programmer needs to tell the language what type a value has, even if the language already thinks it knows what type is correct. This is what typecasting is for. Typecasting accepts a value, and applies a specified type to it. Thus the name: it casts to a type.

This can be very dangerous if used inappropriately, since it can subvert a language's memory management, can corrupt data, can cause inadvertant loss of precision, and can override data hiding. It is also necessary in many languages where the type of particular value is not known until runtime, and cannot be correctly known by the language ahead of time.

In C, a typecast takes the form:

( typeexp ) valueexp

Where valueexp is an expression evaluating to the value that is to be cast, and typeexp is an expression evaluating to the type that the value is to be cast to.

For example, consider the code:

char *str = ( char * ) malloc(SIZE);
strcpy(str , "text");

The code calls malloc which will allocate SIZE bytes on the heap. The result of this call has no useful type, so we tell C that it is a "char *". We can now store this value into a variable "str" which is already of type "char *". The second line treats this variable as a normal instance of its type.

Unfortunately, typecasts are not always easy to spot in C because of the many uses of parentheses in that language.

Typecasting is a little more complicated in C++, and to deal with this situation, C++ introduces several typecasting operators: dynamic_cast, static_cast, const_cast, and reinterpret_cast.

The above is a fairly mundane example, since it only converts between pointer types. There are several more complex (and dangerous) scenarios invovling typecasting which will be covered in the C++ typecast operator nodes.

Being typecast is one of the fears of modern actors. Take Mark Hamill, for example. Everyone knows him as Luke Skywalker, and he hasn't had a decent role since Star Wars. Some folks are able to break out of being typecast, like Drew Barrymore and Alyssa Milano, two squeaky-clean kids who had to work at changing their image. Some folks make a living on their being typecast, like William Shatner and the rest of the Star Trek folks. Talking at conventions and signing autographs keep them in the spotlight and in the minds of their fans. Even when more work comes along, it is usually in the same field, such as Star Trek's Chekov having a recurring role on Babylon 5 as Bester.

The C programming language's syntax for typecasting is very concise: Simply precede an expression with the name of another type in parentheses, and presto! it's the other type.

Now this syntax works in C++, but it has so many problems that the technique has been "deprecated" by the C++ Standard. That is, don't use it in new code.

Watch those fingers! or, Don't do the crime if you can't do the time

The easiest problem to explain. You're taking one of the language's premier features, type safety, and tossing it out the window. "But there are times I really, really need to do this!", you say. And you're right; there are. But they're rare (or should be1), and you really need to think about the consequences of violating type safety before doing it. The easiness of typecasting encourages its use for many problems that are better solved by thinking out their design ahead of time. It's like operating a table saw without a blade guard. Except that violating type safety can lead to far, far more severe consequences than the loss of a couple of fingers.

What's this thing do, anyway?

Another big problem is that casting is used for a whole bunch of tasks that mean different things (i.e. they're semantically different) and had different effects. It all depends upon the type you're casting from and the type you're casting to:

  • Changing a value's representation. C and C++ are full of "standard conversions" that change one type into another. Some are done implicitly, but for others, you have to use a casting operator. Let's say we want to find the integer part of a floating point value. We can say:
    float f = 3.14159;
    int i = (int)f; // i now equals 3
    or, convert an integer into an enumerator:
    enum color {red, green, blue};
    color c = (color)2; // MAYBE color == blue now
    The internal physical representation of the objects changes when we do this. Sometimes bits are simply added or subtracted; other times, as in the float-to-int conversion, the object is completely rearranged.
  • Casting away constness. Let's say you want to assign to a const object. This of course goes against the definition of constness, but sometimes it's necessary (e.g. Windows API calls). And so you can say:
    const int i = 3;
    (int) i = i + 1; // i == 4 now, despite being const
    We're making a promise in one part of the code and breaking it in another!
  • Converting an object of one class type into an object that's a derived class type. This is a form of typecasting that you don't get in C. It's safe as long as the object is really of the derived type:
    class Base {
    virtual ~base() {}
    class Derived: public Base { };
    Base *b = new Derived;
    Derived *d = (Derived *)b;
    There's an analogue in C where you cast a struct object into one of its members:
    struct Baseoid {int i' };
    struct Derivedoid { Baseoid b; int j; };
    Baseoid *b = (Baseoid *) malloc (sizeof(Derivedoid) );
    Derivedoid *d = (Derivedoid*) b;
    b.i = 3;
    d.j = d.b.i; // d.j now == 3
  • Pretending an object is of one type when it's really another type, the kitchen sink of casting. You can convert a pointer into a struct, a function pointer into an integer, anything that isn't well defined in the compiler. This type of casting is like using the different members of a union:
    union { float f;
            int i;
          } u;
    u.f = 3.14159; // I Can guarantee that u.i != 3;
    or even
    float f = (float) u;  // f == 3.14159;
    The compiler has no way to convert betwen the two types, and simply interprets the same bits as if it were the other type.
These all become necessary at times (poor, poor Windows programmer) but they are all deadly dangerous.

Well, then, now what?

Bjarne Stroustrup, the inventor of C++, realized the problems of casting in the late 1980's. The second edition of his book The C++ Programming Language actually described macros for run-time type identification and safer typecasting. These were later incorporated into Standard C++, and appear in the third edition of his book. C++ now has separate operators for the four semantic categories of typecasting:

  • static_castfor well-defined representation conversions, such as builtin conversions, converting derived types to base types, and class type conversion operators.
    enum color {red, green, blue};
    color c = static_cast<color>(2); // MAYBE color == blue now
  • const_cast for casting away constness:
    const int i = 3;
    const_cast<int>(i) = i + 1; // i == 4 now, despite being const
  • dynamic_cast for converting base class objects into derived class objects,
    Derived *d = dynamic_cast<Derived *>(b);
  • and finally reinterpret_cast for everything else:
    float f = reinterpret_cast<float>(u); 

Ugly? Sure! That's the point. Aesthetic justice, I say. You're doing something ugly here, and it has to be labeled with a big ugly red flashing neon sign.

1Pity us poor souls who must program to the Microsoft Windows API.

Log in or register to write something here or to contact authors.