Search code examples
cmallocx86-64backwards-compatibility

sizeof(int*) in 32-bit compatibility mode


Running the following on Linux x86-64 compiled with gcc -m32

#include <stdio.h>
#include <limits.h>

int main() {
    int a = 4;
    int* ptr = &a;

    printf("int* is %d bits in size\n", CHAR_BIT * sizeof(ptr));
    return 0;
}

results in

int* is 32 bits in size

Why I convinced myself it ought to be 64 bits (prior to executing): since it is running on a 64-bit computer in order to address the memory we need 64 bits. Since &a is the address of where value 4 is stored it should be 64 bits. The compiler could implement a trick by having the same offset for all pointers since it is running in the compatibility mode, but it couldn't guarantee congruent data after calling malloc multiple times. This is wrong. Why?


Solution

  • On the hardware level, your typical x86-64 processor has a 32-bits compatibility mode, where it behaves like a x86 processor. That means memory is addressed using 4 bytes, hence your pointer is 32 bits.

    On the software level, the 64 bits kernel allows 32 bits processes to be run in this compatibility mode.

    This is how 'old' 32 bits programs can run on 64 bits machines.

    The compiler, particularly with the -m32 flag, writes code for x86 addressing, so that's why int* is also 32 bits.