Data Types and Pointer Sizes

Because I was bored and because boring repetetive tasks interest me greatly, I wrote a little program that displays data type sizes and compiled it for a variety of platforms immediately available to me.

This is the program.

#include <stdio.h>

int main()
    char *s = ""
        "\nType sizes of current architecture and system\n"
        "char: %d\n"
        "short: %d\n"
        "int: %d\n"
        "long: %d\n"
        "long long: %d\n"
        "float: %d\n"
        "double: %d\n"
        "long double: %d\n"
        "pointer: %d\n\n";
        sizeof(long long)*8,
        sizeof(long double)*8,
        sizeof(char *)*8

It does absolutely nothing useful, only displays the sizes, in bits, of various data types (the last one being a char pointer).

The first three compiled versions were for 32 bit Windows NT (x86 and ARM) and 64 bit Windows NT (AMD64).



The first binary tells us that in 32 bit Windows NT (Windows 10 in this case), a byte is 8 bits long (this is true for all the platforms involved here), an int is a long is 32 bits and a long long is 64 bit. Pointer size of 32 bit Windows NT is, you guessed it, 32 bits.

Windows NT on ARM works exactly the same way. 8 bit bytes, 16 bit shorts, 32 bit ints and longs and 64 bit long longs plus 32 bit pointers.

Note the 64 bit long double floating point type which is identical with the 64 bit double type for all Windows platforms.


64 bit Windows NT simply has a greater pointer size, the most unexpected 64 bit for the 64 bit operating system.

This is called the LLP64 or IL32P64 data model and is used by Windows NT on AMD64 and Itanium.

But on the other hand it should be noted that UNIX, represented here by the favourite Unix clone GNU/Linux, uses 64 bit longs (and 128 bit long doubles). Pointer size is also 64 bit. This is called the LP64 or I32LP64 data model and is used by various operating systems including most UNIX derivatives and clones.

Back in the PC world 32 bit OS/2 just like 32 bit Windows NT. This is of course not a coincidence. Windows NT started its career as Microsoft's planned replacement for OS/2.


OS/2 was a weird 16-32 bit hybrid and also supported 16 bit software.


A 16 bit OS/2 executable lives in a 16 bit world, with 16 bit ints and 16 bit pointers. This is a segmented architecture. While pointers were 16 bit it was possible to address significantly more memory than 64 KB in total.

Note the traditional Windows and OS/2 identity of double and long double.

MS-DOS (note the 8.3 file name) provided (or existed in) a similar environment. The difference was that OS/2's memory addresses were not real. Again this is a segmented architecture.


OpenVMS on Alpha uses the same data model as Windows NT. 64 bit VMS appeared before Windows NT which at the time ran on the Alpha CPU but in 32 bit mode.

But note that OpenVMS does not adhere to the Windows and OS/2 tradition of identical double and long double types.


It is possible on OpenVMS to create a 32 bit executable. This doesn't seem to impact the other data types. I am not sure what it really means.


Note the fact that OpenVMS file names are case-insensitive and cannot contain dots. (Like in MS-DOS the dot separates the file name from the file type specifier. This is actually a good idea.)

 © Andrew Brehm 2016