cwindowsx86x86-64win64

Why is the size of a native long primitive on 64-bit Windows only 4 bytes?


Will someone please tell me how this makes any sense, and how to make it stop? Seriously, am I crazy or is the 64-bit Windows long type only 4 bytes? How does that make any sense? I thought the native long primitive size was supposed to be the same as the native register size.

[32-bit Linux]

me@u32:~$ ./sizes32
sizeof(char):      1
sizeof(short):     2
sizeof(int):       4
sizeof(long):      4
sizeof(long long): 8

[64-bit Linux]

me@u64:~$ ./sizes64
sizeof(char):      1
sizeof(short):     2
sizeof(int):       4
sizeof(long):      8
sizeof(long long): 8

[32-bit Windows]

C:\Users\me\Downloads>sizes32.exe
sizeof(char):      1
sizeof(short):     2
sizeof(int):       4
sizeof(long):      4
sizeof(long long): 8

[64-bit Windows]

C:\Users\me\Downloads>sizes64.exe
sizeof(char):      1
sizeof(short):     2
sizeof(int):       4
sizeof(long):      4
sizeof(long long): 8

Solution

  • Backward compatibility!

    Windows came from a 16-bit platform where sizeof(long) == 4 and it makes extensive use of custom types like LONG, DWORD... in its API. Microsoft takes a very serious stance on backward compatibility (sometimes even modifying its code to make stupid old code work) and changing that would make a lot of issues

    Over on Channel 9, member Beer28 wrote, "I can't imagine there are too many problems with programs that have type widths changed." I got a good chuckle out of that and made a note to write up an entry on the Win64 data model.

    The Win64 team selected the LLP64 data model, in which all integral types remain 32-bit values and only pointers expand to 64-bit values. Why?

    In addition to the reasons give on that web page, another reason is that doing so avoids breaking persistence formats. For example, part of the header data for a bitmap file is defined by the following structure:

    typedef struct tagBITMAPINFOHEADER {
            DWORD      biSize;
            LONG       biWidth;
            LONG       biHeight;
            WORD       biPlanes;
            WORD       biBitCount;
            DWORD      biCompression;
            DWORD      biSizeImage;
            LONG       biXPelsPerMeter;
            LONG       biYPelsPerMeter;
            DWORD      biClrUsed;
            DWORD      biClrImportant;
    } BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
    

    If a LONG expanded from a 32-bit value to a 64-bit value, it would not be possible for a 64-bit program to use this structure to parse a bitmap file.

    Why did the Win64 team choose the LLP64 model?