Search code examples
cpointerscasting

Typecasting of pointers in C


I know a pointer to one type may be converted to a pointer of another type. I have three questions:

  1. What should kept in mind while typecasting pointers?
  2. What are the exceptions/error may come in resulting pointer?
  3. What are best practices to avoid exceptions/errors?

Solution

  • A program well written usually does not use much pointer typecasting. There could be a need to use ptr typecast for malloc for instance (declared (void *)malloc(...)), but it is not even necessary in C (while a few compilers may complain).

      int *p = malloc(sizeof(int)); // no need of (int *)malloc(...)
    

    However in system applications, sometimes you want to use a trick to perform binary or specific operation - and C, a language close to the machine structure, is convenient for that. For instance say you want to analyze the binary structure of a double (that follows thee IEEE 754 implementation), and working with binary elements is simpler, you may declare

      typedef unsigned char byte;
      double d = 0.9;
      byte *p = (byte *)&d;
      int i;
      for (i=0 ; i<sizeof(double) ; i++) { ... work with b ... }
    

    You may also use an union, this is an exemple.

    A more complex utilisation could be the simulation of the C++ polymorphism, that requires to store the "classes" (structures) hierarchy somewhere to remember what is what, and perform pointer typecasting to have, for instance, a parent "class" pointer variable to point at some time to a derived class (see the C++ link also)

      CRectangle rect;
      CPolygon *p = (CPolygon *)&rect;
      p->whatami = POLY_RECTANGLE; // a way to simulate polymorphism ...
      process_poly ( p );
    

    But in this case, maybe it's better to directly use C++!

    Pointer typecast is to be used carefully for well determined situations that are part of the program analysis - before development starts.

    Pointer typecast potential dangers

    • use them when it's not necessary - that is error prone and complexifies the program
    • pointing to an object of different size that may lead to an access overflow, wrong result...
    • pointer to two different structures like s1 *p = (s1 *)&s2; : relying on their size and alignment may lead to an error

    (But to be fair, a skilled C programmer wouldn't commit the above mistakes...)

    Best practice

    • use them only if you do need them, and comment the part well that explains why it is necessary
    • know what you are doing - again a skilled programmer may use tons of pointer typecasts without fail, i.e. don't try and see, it may work on such system / version / OS, and may not work on another one