Consider the following small example code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *i;
char *c1, *c2;
i = malloc(4);
*i = 65535;
c1 = i;
c2 = (char *)i;
printf("%p %p %p\n", i, c1, c2);
printf("%d %d", *c1, *c2);
free(i);
return 0;
}
In the example, I allocate memory to store an integer, which is pointed by i
. Then, I store the value 65535 (1111 1111 1111 1111) in *i
. The next thing I do is make two char* pointers also point to the integer. I do it two times, but in two different ways: c1 = i;
and c2 = (char *)i;
. Finally, I print all pointers and all values in the screen. The three pointers are pointing to the same address, and the two values *c1
and *c2
are correct (-1).
However, the compiler generates a warning in this line: c1 = i;
. The warning is generated because I did not use the (char *)
cast to do the assignment.
What I would like to ask is why the compiler generates this warning, since I do not see any difference in using c1 = i
; or c2 = (char *)i;
. In both cases, the result is the same address with the same size in bytes. And this is valid for all casts, even if it is a (int *)
cast, (float *)
cast, (short *)
cast, etc. All of them generate the same value, but the compiler will only accept it without a warning if the cast being used is of the pointer's type.
I really would like to know why the compiler asks for that cast, even if the result is always the same.
A pointer is an arrow that points to an address in memory, with a label indicating the type of the value. The address indicates where to look and the type indicates what to take. Casting the pointer changes the label on the arrow but not where the arrow points.
Pointer casting is usually used when you want to access the bit stream pointed by one type of pointer and read it as something else. The requirements have to be specific enough and you have to be really careful when doing this. When the destination pointer type points to character type, it's okay to use it.
Casting a pointer to a different pointer and back is usually safe and yields the original value. The limitations are that object pointers can be cast only to object pointers with similar or stricter alignment requirements, and function pointers can be cast only to function pointers.
Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
When you use:
c2 = i;
the compiler warns you about the assignment of type int*
to char*
. It could potentially be an inadvertent error. The compiler is warning you with the hope that, if it is indeed an inadvertent error, you have the chance to fix it.
When you use:
c2 = (char *)i;
you are telling the compiler that you, as the programmer, know what you are doing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With