Memory addressing and pointers in C

Yes. Raw pointer is 32 bits of data (or 16 or 64 bits, depending on architecture), and does not contain anything else. Whether it's int *, char *, struct sockaddr_in * is just information for compiler, to know what is the number to actually add when incrementing, and for the type it's going to have when you dereference it.


Your hypothesis is correct: to see how different kinds of pointer are handled, try running this program:

int main()
{
    char * pc = 0;
    int * pi = 0;

    printf("%p\n", pc + 1);
    printf("%p\n", pi + 1);

    return 0;
}

You will note that adding one to a char* increased its numeric value by 1, while doing the same to the int* increased by 4 (which is the size of an int on my machine).


It is indeed syntactic sugar. Consider the following code fragment:

int t[2];
int a = t[1];

The second line is equivalent to:

int a = *(t + 1); // pointer addition

which itself is equivalent to:

int a = *(int*)((char*)t + 1 * sizeof(int)); // integer addition

After the compiler has checked the types it drops the casts and works only with addresses, lengths and integer addition.


You might be confused by compile time versus run time.

During compilation, gcc (or any C compiler) knows the type of a pointer, in particular knows the type of the data pointed by that pointer variable. So gcccan emit the right machine code. So an increment of a int * variable (on a 32 bits machine having 32 bits int) is translated to an increment of 4 (bytes), while an increment of a char* variable is translated to an increment of 1.

During runtime, the compiled executable (it does not care or need gcc) is only dealing with machine pointers, usually addresses of bytes (or of the start of some word).

Types (in C programs) are not known during runtime.

Some other languages (Lisp, Python, Javascript, ....) require the types to be known at runtime. In recent C++ (but not C) some objects (those having virtual functions) may have RTTI.

Tags:

C