Reputation: 2865
So I'm learning about C pointers, and I'm a little confused. Pointers just point to specific memory address.
sizeof(char*)
, sizeof(int*)
, sizeof(double*)
all output 8
. So they all take 8
bytes to store a memory address.
However, if I try to compile something like this:
int main(void)
{
char letter = 'A';
int *a = &letter;
printf("letter: %c\n", *a);
}
I get a warning from the compiler (gcc
):
warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int *a = &letter;
However, char *a = &letter;
, doesn't result in a warning.
Why does the type of the pointer matter, if it's 8
bytes long anyway? Why does declaring a pointer with a type different than the type of data it's pointing to yield in a warning?
Upvotes: 2
Views: 79
Reputation: 263217
Think about what you're going to do with the pointer.
int n = 42;
char *p = &n; // BAD
If this compiles (a compiler can reject it outright rather than printing a non-fatal warning), you have a pointer that points to the memory occupied by the int
object n
. How are you going to get the value of that object? *p
gives you a char
result, most likely the first byte of n
-- which may be the high-order byte or the low-order byte.
Pointer types depend on the type of object they point to so that you can access that object.
(Also, don't make assumptions based on the behavior of your particular implementation. 32-bit systems have 4-byte pointers, and the language doesn't guarantee that all pointers are the same size.)
Upvotes: 2
Reputation: 372714
The issue isn't about the size of the pointer - it's about the type of the pointee.
If you have a pointer to an int
, the pointer takes up some number of bytes (seems like you have a 64-bit system, where that pointer takes up eight bytes). However, if you dereference that pointer to read or write what it points to, because the type of the pointer is int*
, the read or write will try to manipulate sizeof(int)
bytes at the target, and it will try to manipulate them as though they're an int
.
If you have a single object of type char
, which by definition has size 1, and you try to read or write it through a pointer of type int
, which (on many systems) has size 4, then reading the pointer will pull back some garbage data along with the char
and writing to the pointer will clobber random regions of memory around that char
with unrelated values.
Additionally, C has a rule called the strict aliasing rule that says that you are not allowed to read or write through a pointer of a type that doesn't match the type of what's being pointed at (unless the pointer is of type char *
, signed char*
, or unsigned char*
). Breaking strict aliasing can mess up all sorts of compiler optimizations and lead to code that doesn't behave as expected.
So in short, the size of the pointer really isn't the issue here. It's the semantics about what happens when you try to read or write what's being pointed at.
Upvotes: 6
Reputation: 366
It's not about bytes length but about the type of what you're pointing to. Char
and int
are completly different. Moreover, sizeof(char)
equal 1 and sizeof(int *)
equal 8.
Upvotes: 0