Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting void pointers

I've seen a lot of the following in older C code:

type_t *x = (type_t *) malloc(...);

What's the point of casting the pointer returned from malloc() since it's void *? Is it because older C compilers didn't support void pointers and malloc() used to return char * instead?

like image 389
Blagovest Buyukliev Avatar asked Aug 24 '10 18:08

Blagovest Buyukliev


People also ask

Can you cast a void pointer?

A void pointer can hold address of any type and can be typecasted to any type.

How do I cast a void pointer to integer?

After declaration, we store the address of variable 'data' in a void pointer variable, i.e., ptr. Now, we want to assign the void pointer to integer pointer, in order to do this, we need to apply the cast operator, i.e., (int *) to the void pointer variable.

Should you use void pointers?

We use the void pointers to overcome the issue of assigning separate values to different data types in a program. The pointer to void can be used in generic functions in C because it is capable of pointing to any data type.

What does casting to void do?

Cast to void to silence warnings The (void) casts and the comment are for human readers. Casting an expression to void explicitly throws away that expression's value. This tells readers that the programmer intended to write a do-nothing expression. Otherwise a reader might think it was a mistake.


2 Answers

Your own explanation is the right one. Pre-ANSI C ('K&R' C) did not have a void * type with implicit conversion. char * doubled as a pseudo void * type, but you needed the explicit conversion of a type cast.

In modern C the casting is frowned upon because it can suppress compiler warnings for a missing prototype of malloc. In C++, the casting is needed (but there you should be using new instead of malloc most of the time).

Update

My comments below that try to explain why the cast is required were a bit unclear, I'll try to explain it better here. You might think that even when malloc returns char *, the cast is not needed because it is similar to:

int  *a;
char *b = a;

But in this example a cast is also needed. The second line is a constraint violation for the simple assignment operator (C99 6.5.1.6.1). Both pointer operands need to be of compatible type. When you change this to:

int  *a;
char *b = (char *) a;

the constraint violation disappears (both operands now have type char *) and the result is well-defined (for converting to a char pointer). In the 'reverse situation':

char *c;
int  *d = (int *) c;

the same argument hold for the cast, but when int * has stricter alignment requirements than char *, the result is implementation defined.

Conclusion: In the pre-ANSI days the type cast was necessary because malloc returned char * and not casting results is a constraint violation for the '=' operator.

like image 195
schot Avatar answered Sep 25 '22 22:09

schot


The problem here is not compatibility with any dialect of C. The problem is C++. In C++, a void pointer cannot be automatically converted to any other pointer type. So, without an explicit cast, this code would not compile with a C++ compiler.

like image 32
slacker Avatar answered Sep 24 '22 22:09

slacker