bool3max
bool3max

Reputation: 2865

Why are C pointers recommended to be the type of the data they're pointing to, if they're 8 bytes large regardless?

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

Answers (3)

Keith Thompson
Keith Thompson

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

templatetypedef
templatetypedef

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

Nicolas Guerin
Nicolas Guerin

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

Related Questions