Search code examples
cpointerscastingvoid

Should/Do I cast a void pointer in C in general?


In Do I cast the result of malloc? it is said, that you do not need to cast the returned void pointer of the malloc() function or one of its family members, because since the standard it can be omitted and it may cause a hand of issues.

But what about the casting of a void pointer in general? Is there any difference to the general approach of casting a void pointer?

  • Should cast a void pointer to another type pointer in general in C?
  • Are there any places in C where I do cast a void pointer?

Solution

  • There are two correct cases where you need to have a cast:

    • to convert a pointer to a void back to its original non-void type without assigning the result to a variable (assignment including initialization, or passing it as an argument).

    • to silence a stupid compiler that gives a warning about a narrowing conversion. C11/C18 Annex I:

      1. An implementation may generate warnings in many situations, none of which are specified as part of this International Standard. The following are a few of the more common situations.

      2. [...]

        • An implicit narrowing conversion is encountered, such as the assignment of a long int or a double to an int, or a pointer to void to a pointer to any type other than a character type (6.3).

    For the first part: you can pretty much always use a temporary variable. For example you can either write

    int comparator(const void *a, const void *b)  
    { 
        int sa = ((const struct foo *)a)->bar; 
        int sb = ((const struct foo *)b)->bar;  
        return (sa > sb) - (sa < sb); 
    } 
    

    or

    int comparator(const void *a, const void *b)  
    { 
        const struct foo *sa = a; 
        const struct foo *sb = b;  
        return (sa->bar > sb->bar) - (sa->bar < sb->bar); 
    } 
    

    - they're pretty much equivalent in number of keypresses.

    And for the second case you just need to avoid such compilers or try to switch off that nagging with some switches.


    Beyond that the question rather is, "should I have a cast where it is not needed". There are many things that are not necessary in a C program but are added for clarity. For example indentations or newlines! Adding them makes things so much clearer. The question is whether adding a useless cast for return value from malloc for example makes it more readable:

    char *foo = malloc(42);
    

    vs

    char *foo = (char *)malloc(42);
    

    Isn't it rather obvious that the result should be converted to char * or at least that of foo even without a cast?