22

From the earliest K&R reference manuals I read, 'int' was synonymous with machine word and it seemed to raise adverse reactions in various user domains. With the UNIX crowd, they minimally required an MMU(Note *1) so the word had to be 32bits at least to do memory management without segmentation overhead such as we saw with 16bit WinTel memory models (tiny, large, huge etc), so the UNIX machines started with 32bits as a minimum for the preferred flat address space.

But that did not define the C int. I also note that the DB crowd have had a preference for immutable storage specifications, so perhaps they too shunned the semantic int for an imperative one.

The reason I ask is that I notice this sudden appearance of an access barrier where manufactured storage disks easily exceed 2TB which but is pegged by the 'long int's stuck on 32 bit 'int's. But the C int specification should not have forced the 32bit word size that now makes the 32bit semantic incapable of implementing 4TB disk access (by mere recompile) to that of 64bit native word machines?

So if there does exist an explicit standard where 'int' is mandated to 32 bits does anyone know its origins (ANSI? IEEE? POSIX? OTHER? etc) and the motivation for that dramatic change from the K&R specification?

If the 32bit standard was made 'pragmatically' then it would surely be equivalent to that other 640K limit which we once lived to regret.

Feedback is pointing towards pragmatism thus far, for instance the Win64 (Answer by @ssokolow): 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.

And the Amdahl 64 = 32x2 comment given by @ faddenon on the experience of bridging the large double jump from 32 to 64. I give a similar current Redhat/CentOS 8 file access structure that has hidden 32bit ints all over (man statx; from man inode):

   struct statx {
       __u32 stx_mask;        /* Mask of bits indicating
                                 filled fields */
       __u32 stx_blksize;     /* Block size for filesystem I/O */
       __u64 stx_attributes;  /* Extra file attribute indicators */
       __u32 stx_nlink;       /* Number of hard links */
       __u32 stx_uid;         /* User ID of owner */
       __u32 stx_gid;         /* Group ID of owner */
       __u16 stx_mode;        /* File type and mode */
       __u64 stx_ino;         /* Inode number */
       __u64 stx_size;        /* Total size in bytes */
       __u64 stx_blocks;      /* Number of 512B blocks allocated */
       __u64 stx_attributes_mask;
                              /* Mask to show what's supported
                                 in stx_attributes */

       /* The following fields are file timestamps */
       struct statx_timestamp stx_atime;  /* Last access */
       struct statx_timestamp stx_btime;  /* Creation */
       struct statx_timestamp stx_ctime;  /* Last status change */
       struct statx_timestamp stx_mtime;  /* Last modification */

       /* If this file represents a device, then the next two
          fields contain the ID of the device */
       __u32 stx_rdev_major;  /* Major ID */
       __u32 stx_rdev_minor;  /* Minor ID */

       /* The next two fields contain the ID of the device
          containing the filesystem where the file resides */
       __u32 stx_dev_major;   /* Major ID */
       __u32 stx_dev_minor;   /* Minor ID */
   };

No culprits yet, but I suspect IEEE the 'real' pragmatists.

*1) NetBSD which claims portability onto anything requires it to have an MMU

26
  • 19
    What does the 2TiB limit have to do with the size of int in C? Sep 29, 2020 at 14:13
  • 14
    Those comments about mmu and 32 bit are wrong. I use a real Unix from 77 that’s real mode, 16 bit
    – pm100
    Sep 29, 2020 at 14:18
  • 28
    C still does not say what size int is. Just the relationship of the sizes of short, int and long
    – pm100
    Sep 29, 2020 at 14:19
  • 18
    The amount of data that’s addressable on a drive isn’t determined by the C standard, it’s determined by the standard defining the protocol used to access the drive (SCSI, SATA etc.) and that doesn’t use C data types, it specifies the number of bits to use. Current addressing schemes on ATA-based standards use 48 bits. Sep 29, 2020 at 14:19
  • 6
    Re, "manufactured storage disks", @StephenKitt addresses the hardware aspect of that (i.e., what you need to know if you're writing device drivers), but If you're writing user-mode application code in C or in C++, and if your code needs to know byte offsets within a file, then you should store those in size_t variables. Sep 29, 2020 at 14:29

10 Answers 10

13

What should be emphasized more because it is perhaps unexpected is that the C standard and POSIX differ in their requirements for the value range of an int. Specifically and importantly, C never mandated 32 bit int sizes. The reason for the discrepancy may be in the different assumptions each standard can make about the hardware.

C is used for a wide variety of programming tasks. Importantly, because it compiles directly to machine code and does not need a huge runtime, it is the language of choice for programming small embedded systems and microcontrollers, often with freestanding implementations: Such systems don't have an operating system, obviously no shell, no processes etc. The requirements the language imposes on C implementations running on such small hardware cannot be too restrictive or they would be broken all the time and hence be useless.

A publicly available ISO C standard draft from 2007, for example, specifies in §5.2.4.2.1

[The] implementation-defined values [from limits.h] shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

The "minimal maximum" for int is then given as

— maximum value for an object of type int
INT_MAX +32767     // 215 - 1

By contrast, a POSIX system runs an operating system kernel with *nix-like features (multi-user, multi-tasking among them), provides an elaborate command shell etc. Clearly this requires a much more capable hardware. Which is presumably why the current POSIX standard mandates at a minimum 32 bit integers:

{INT_MAX}
Maximum value for an object of type int.
[CX] [Option Start] Minimum Acceptable Value: 2 147 483 647

The "CX" marks this requirement as an extension to the C standard:

[CX] [Option Start] Extension to the ISO C standard [Option End] The functionality described is an extension to the ISO C standard. Application developers may make use of an extension as it is supported on all POSIX.1-2017-conforming systems. [...]

Where additional semantics apply to a function or header, the material is identified by use of the CX margin legend.

0
55

The C standard of the language doesn't mandate a 32-bit int. It defines

sizeof(char) = 1

and

sizeof(long long)sizeof(long)sizeof(int)sizeof(short)sizeof(char)

It also mandates that the constant in limits.h are at least the values given below

#define CHAR_BIT 8
#define CHAR_MAX UCHAR_MAX or SCHAR_MAX
#define CHAR_MIN 0 or SCHAR_MIN
#define INT_MAX +32767
#define INT_MIN -32767
#define LONG_MAX +2147483647
#define LONG_MIN -2147483647
#define LLONG_MAX +9223372036854775807
#define LLONG_MIN -9223372036854775807
#define MB_LEN_MAX 1
#define SCHAR_MAX +127
#define SCHAR_MIN -127
#define SHRT_MAX +32767
#define SHRT_MIN -32767
#define UCHAR_MAX 255
#define USHRT_MAX65535
#define UINT_MAX 65535
#define ULONG_MAX 4294967295
#define ULLONG_MAX 18446744073709551615

This means that int can be 16 bit or 64 bit, there's no requirement for 32 bit.

As far as I know, POSIX doesn't go beyond that requirement. The only thing that POSIX mandates is that pointer (including function pointer) can be converted to long and back. This is required for shared objects (dynamic libraries).

The standard ISO/IEC 9899:1999 aka C99 can be consulted here http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf There are newer standards (C11) but C99 is imho more relevant.

9
  • 2
    Some old computer that were K&R would not be conformant. For example Megamax-C for the Atari ST defined short as being 8 bit wide. This would violate the SHRT_MAX requirment for example. Sep 29, 2020 at 14:56
  • 10
    Some embedded C compiler, notably for TI DSP processors have all types, from char to long be 32 bit wide and still are conformant. Sep 29, 2020 at 14:57
  • 4
    No. Chapter 6.2.6.2 constraints would make it unworkable. open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf Sep 29, 2020 at 15:11
  • 14
    POSIX SUSv2 does go beyond that requirement by mandating that int must have at least 32 bits. Later POSIX also requires that CHAR_BIT == 8
    – phuclv
    Sep 30, 2020 at 1:39
  • 6
    @OmarL: int has to hold all integer values between -32767 and +32767, so it requires at least 16 bits. But Cray supercomputers did in fact use (larger) float registers to store ints. That was possible because those registers could store -32767.0 to +32767.0 and all integers in between. So sizeof(int)==4 can still occur when INT_MAX=32767.
    – MSalters
    Oct 1, 2020 at 9:21
37

The C standard only requires that the int type be at least 16 bits wide. There's no requirement that int be 32 bits, though it's a very common implementation choice these days. An exception would be C compilers targeting 8-bit embedded systems which mostly use a 16-bit int.

(Note the C standard specifically requires that int be able to hold a value in the range -32,767 to 32,767 inclusive. There's no requirement that it be able to hold the value -32,768, allowing for sign-magnitude and ones' complement representations.)

The first C compiler was written for Unix running on the PDP-11 and used a 16-bit int. So there wasn't a requirement in the Unix world that int be 32 bits either. Originally POSIX didn't place any additional requirements on int over the C standard, but in 2001 POSIX adopted the Single Unix Specification which requires at least a 32-bit int (though still allowing sign-magnitude and ones' complement representations.) However, unlike Standard C compliance which is commonly claimed by C compilers, very few current operating systems claim to be fully POSIX/SUS-compliant. Most environments that use a 32-bit int are doing so voluntarily.

These days, with the exception of certain embedded systems mentioned above, a 32-bit int is the universal choice of C implementations. In the past there have also been C compilers that used a 36-bit int (for Honeywell GCOS systems) and a 64-bit int (for Cray supercomputers), and of course MS-DOS C compilers used a 16-bit int, but these are all long obsolete.

When 64-bit CPUs became a thing, it might have seemed natural for C compilers targeting these CPUs to use a 64-bit int, but in practice this would've produced slower code because of the increased data size, while adding additional difficulty in porting software to the CPUs.

5
  • 1
    Another example of a C compiler with 36-bit ints: kcc, which targets the PDP-10. Oct 1, 2020 at 8:06
  • 3
    Does POSIX require exactly 32-bit, or at least 32-bit int? @phuclv commented that it was "at least" in SUSv2. Oct 1, 2020 at 11:02
  • 1
    Re: keeping 32-bit int for 64-bit machines: indeed, most/all 64-bit ISAs have efficient hardware support for 32-bit operand-size, at least for some common operations (e.g. Alpha), unlike with 16-bit short on 32-bit machines. (related: C++ int vs long long in 64 bit machine) Oct 1, 2020 at 11:05
  • @PeterCordes Yes, I should've said at least 32 bits.
    – user722
    Oct 1, 2020 at 14:31
  • The biggest practical problem with 64-bit int is that the implementation then either has to omit or use a nonstandard type for one of int8_t/int16_t/int32_t, because there are only two standard integral types (char and short) smaller than int.
    – dan04
    Jul 30, 2021 at 20:44
21

There is no such requirement in standard C. Traditionally, an int was required to be at least 16 bits, though since the mid-1980s I started to write code as if an int was at least 32 bits, confident I did not intend to support older hardware.

When we moved to 64-bit systems, it was common in some implementations for int to remain at 32 bits, since this eased porting code that had made that assumption.

The first implementation of Unix, and C, was on the PDP-11, a 16-bit machine, so sizeof (int) was 2. The first port of Unix, to an Interdata 7/32. made sizeof (int) be 4.

But the question is confused on other matters.

Unix originally ran on PDP-11 (and without an MMU, either - at least until Thompson and Ritchie got an 11/40), which is a 16-bit machine, and int in C was defined as a 16-bit machine word.

None of this is anything to do with file system size limits. 16-bit CPUs could and did support 32-bit file sizes (or larger, but practical concerns may not have made that sensible). 32-bit CPUs could, did, and do support 64-bit file sizes.

There is a potential problem with API defined in C terms. For example, PDP-11's seek() syscall had to become lseek() when disks could support more than 64K blocks, and an int argument was no longer sufficient.

Windows on 32-bit hardware (the NT family at least) supported 64-bit file sizes, offsets, etc., by the simple expedient of providing two 32-bit arguments to hold a 64-bit value -- either as two actual function arguments, or as a single struct that had two 32-bit members.

0
16

If you need a date, then March 12, 1997. That's when Single UNIX Specification version 2 (aka UNIX98) was released. Among other changes to the ISO C standard (via limits.h), INT_MAX and INT_MIN were changed to 2,147,483,647 and -2,147,483,647, respectively (the same as LONG_MAX and LONG_MIN). This of course does not mandate a 32-bit int (64-bit ints are compliant) and it doesn't affect the ISO/ANSI C standards.

13
  • 1
    I assume this is POSIX? It, as you say, does not mandate a 32bit int, but I cannot see how one can comply without forcing 32 bit signed on ints.(!!) Is this my smoking gun? (PS: Were there any card-carrying IEEE members on that commitee? heh heh!)
    – MKhomo
    Sep 30, 2020 at 7:46
  • 1
    Changes to the C standard? No, they don't have the authority. Requirements on top of the C standard? Sure, they need and want to guarantee more, that's fine. Sep 30, 2020 at 12:05
  • 2
    Yes, that's POSIX. It sets 32-bit as the minimum int size. But anything bigger (36-bits, 64-bits, 128 bits) would also be valid int, so it's not a requirement to be exactly 32-bit. Sep 30, 2020 at 12:51
  • 2
    @MKhomo It didn't become POSIX until 2001 when POSIX adopted the SUS as a standard. Previously they were separate standards.
    – user722
    Sep 30, 2020 at 17:30
  • 1
    While this is the only answer that tries to give a date, very strictly speaking, it doesn't answer the question. The C standard never asked for 32 bits, what you're referring to is "additional requirements over the C standard that apply to a C compiler for a POSIX-compliant system" - That's something different. Embedded systems, for example, would never strive to be POSIX-compliant, but can still have a ISO-C-compliant compiler.
    – tofro
    Oct 3, 2020 at 9:57
10

When C was invented, there was no particular reason why an implementation would want to use a value for int which was smaller than a register. Although the Standard allowed implementations to choose almost any means they wanted to pick the sizes of integer types, the common practice was that, absent any reason to do otherwise:

  • char would be the smallest addressable unit that was at least 8 bits (even platforms with bit-addressable or nybble-addressable storage were required to make all pointers be multiples of char).

  • short would be the smallest practical type that was at least 16 bits.

  • long would be the smallest practical type that was at least 32 bits.

  • long long, when supported, would be the smallest practical type that was at least 64 bits.

  • int would be at least large as short, but could be the smallest type of at least 32 bits on platforms that could process such values at about the same speed as smaller ones.

On some platforms like the 68000, 32-bit computations were about 30-50% slower than 16-bit ones, so compilers for that platform often allowed programmers a choice of whether int should be 16 or 32 bits. On platforms where there would be a 2:1 speed difference, int would typically be 16 bits, and on those where there was no speed difference or 32-bit math would be faster, int would typically be 32 bits, but on the 68000 the speed difference fell right in the middle.

Note that it's often considered desirable to have a standard integer type for each each power-of-two size from 8 bits to 64 bits. If int were 64 bits, there would only be two standard types that were smaller than 64 bits, which wouldn't be enough to have a type available for each of the common object sizes (8, 16, 32).

3
  • I can see now a preference for speed keeping int's at a preferred size at a particular time of implementation. I suppose the same can be said of the compiled image size where N instructions doubled the image size with plenty superfluous bloat.
    – MKhomo
    Sep 29, 2020 at 18:00
  • @MKhomo ARM Thumb-mode is a contemporary equivalent.
    – crasic
    Sep 30, 2020 at 19:55
  • I must hand it to chip-set designers for their level of ingenuity. Another comment pointed out alternating int sizes on the 68k motorola chip set I think, possibly now a maxscale brand.
    – MKhomo
    Sep 30, 2020 at 20:41
10

The book "Writing Solid Code" documents an instance where the size of an int changed. There is a section which noted that (once upon a time) Microsoft's own internal C code sources often hard-coded the value '2' (bytes) instead of writing 'sizeof(int)', under the theory that "... well, we OWN the C compiler -surely our own compiler group wouldn't change something as fundamental as the size of an int!". They then proceeded to do exactly that. Broke a lot of code - lots of embarrassment all around ['course that was back in the 80's].

5
  • 1
    Sounds bizarre, but once I saw the C compiler headers for DOS, coming from BSD UNIX I can sympathise with MS's programmers. It eventually led to name standards police and Hungarian Notation just to maintain sanity. When C++ came along Hungarians mandated they all are little 'm~', and that's become universal and even in Java where class identifiers are big ^[A-Z] with little m's redundant. Later they acquired branded Lattice C as MSC Compiler V6 or something. But that had to have come from Intel engineers.
    – MKhomo
    Sep 29, 2020 at 21:15
  • 4
    But this is just a Microsoft implementation, not "the C language" itself.
    – dave
    Sep 29, 2020 at 23:40
  • 1
    and even within Microsoft, I would suppose that sizeof (int) == 2 on 16-bit systems, and 4 on 32-bit systems. It's not like they changed the size on a single system.
    – dave
    Sep 30, 2020 at 1:06
  • 1
    @MKhomo It was much earlier that Microsoft rebranded Lattice. According to Wikipedia and one of its sources, MS C v 3.0 was the first version written in-house. Like you, I thought that Microsoft had bought Lattice, but it seems not.
    – grahamj42
    Sep 30, 2020 at 6:33
  • Also looked at Wikipedia and saw the mention that Lattice C (the brand) is servicing mainly mainframe compilers. I cannot think it not coming out of Intel. And, at some stage Intel was going under over AMD 286 IP and IBM bailed them out. Perhaps that could be how the current Lattice compiler target is mainframe. (Watch for future Java focus on VARCHAR :)
    – MKhomo
    Sep 30, 2020 at 9:45
7

With the UNIX crowd, they minimally required an MMU so the word had to be 32bits at least to do memory management without segmentation overhead

Not true. The PDP-11 had a 16 bit word size and a 16 bit address size which meant that user space processes were limited to 64 kilobytes. I'm not 100% certain but I think that int and char * were both 16 bits for C compilers targeted at the PDP-11. The PDP 11 ran Unix just fine.

But that did not define the C int.

The C int was usually but not always selected to be the optimal size for the target processor. I wouldn't say it was a standard but it was an informal "best practice". For example, the Megamax C compiler that I used with my Atari ST had a 16 bit int because that was the fastest size on a 68000. It did, however, have a 32 bit pointer size because that was the size of the address registers. That used to cause me all sorts of problems with porting code because a surprising amount of it assumed that int and char * were the same size.

On the other hand, the more sophisticated and (crucially for me) more expensive Mark Williams C used 32 bits for both int and char *.

The reason I ask is that I notice this sudden appearance of an access barrier where manufactured storage disks easily exceed 2TB which but is pegged by the 'long int's stuck on 32 bit 'int's. But the C int specification should not have forced the 32bit word size that now makes the 32bit semantic incapable of implementing 4TB disk access (by mere recompile) to that of 64bit native word machines?

Any limits of that nature would be far more complicated than simply "the size of an int". For example, it might be the size of an int times the size of a block or cluster. It really depends on the operating system or the file system, not the compiler. The C definitions of the stat structure are not prescriptive, they are descriptive. i.e. as a rule, the OS defines how big a thing is and the C declaration has to match it, not the other way around.

3
  • I fully understand the difficulties you raise, and how headers like limits.h protected portability, interoperability and the rest of it. And I can see how the file systems are the derterminant and not system primitives of their implementation language. It's more the OS vision. So if I were to think futuristic in a Hurd way, I'd start with an "unlimited.h" resource file where all the things that do not need to have a mandated limit go. These would be provisioned resources mainly, so things like a 640K memory max or disk storage access would not sneak in through internal system structures.
    – MKhomo
    Sep 30, 2020 at 8:34
  • I think with disks, we're currently in an unusual period where the physics and technology built into Moore's law has outpaced software's ability to guzzle emergent h/w capacity.
    – MKhomo
    Sep 30, 2020 at 8:38
  • Perhaps the same could be said of 5G bandwidth stuck in the hands of carriers ...
    – MKhomo
    Sep 30, 2020 at 8:46
7

As a couple of people have noted, Unix originally ran on the PDP-11,¹ which had 16-bit pointers and ints. The original PDP-11/20, which Unix first ran on, had no MMU, but one was added in the PDP-11/45, which was still 16-bit. By V6, Unix implemented a form of virtual memory by copying entire programs in and out of memory as needed.

(Interesting side-note: the shell on V1 had about 350 lines of assembler source code. Large programs, like the C compiler and the assembler, were split into two executables, which communicated using temporary files. PDP-11 Unix programs were probably too small to page! Paging, like 32-bit computing, was introduced by the port of BSD to the VAX.)

Beyond that, Xenix ran on 8086s (with a non-standard MMU, so not 100% IBM-compatible) and 80286s, with a segmented memory architecture and 32-bit pointers but 16-bit ints.

That had interesting consequences when passing a literal 0 to a K&R C function taking a pointer (no prototypes back then!), or to a variadic function like execl. I think things like the NULL symbolic constant come from that background, where an unambiguously pointer-sized 0 was needed.

(According to DMR, the original Unix machine had 24KB of memory installed, which is a bit larger than the original IBM PC's 16KB, but less than half of what a 16-bit address space can handle. This link says V1 processes had 8KB of 'userspace' memory available to them. Of course, by the 1980s Unix programs had expanded to require a bit more memory!)

¹ Technically Unix development started on the PDP-7, but development moved to the PDP-11 before V1, and long before anything we would recognize as 'Unix' today. (The kernel was rewritten in C for V4, in 1973, and for ease of development, not for portability yet.) V6 (1975), which was the first widely-distributed Unix, and V7 (1979), which was the common ancestor of all 'modern' Unixes, including the *BSDs, both ran primarily on the PDP-11. (Although by V6 porting efforts to other machines had started.)

7
  • 4
    PDP-11 C had 8-bit chars, not 16-bit chars. Typo? And the first PDP-11 Unix was on an 11/20, a machine with no MMU. Though I'm not sure at what time C came in.
    – dave
    Oct 1, 2020 at 1:10
  • AFAICT, the early versions of Unix that ran on the PDP-11/20 required the memory to be expanded to the maximum 28kwords (56kbytes). See github.com/jserv/unix-v1/blob/master/notes/machine.txt for a description of the machine that the earliest extant version of Unix run on. It seems the system used 12kwords just for the kernel, and 16kwords were required for the running user space program. By this time, C was already in use. AIUI, C was introduced to the Unix kernel during the rewrite to switch to the PDP-11.
    – occipita
    Oct 1, 2020 at 10:39
  • By 1990 Unix users got a real workstation running some kind of Unix (SunOS/Irix/whatever) depending on what they needed it for. Those were too expensive for private users, but not uncommon in the university world. Oct 1, 2020 at 14:20
  • 1
    @occipita - that link specifically says they had only 24KB of memory on the lab's PDP-11/20. Every source I've read says the V1 kernel was ASM. Oct 19, 2020 at 6:13
  • 1
    @another-dave+ the BellLabs 11/20 did have memory mapping, though not the 8x8KB x sometimes I/D x K/[S]/U that became standard on 11/40 and up (and then 11/34 and LSI-11/23 and 73) -- according to dmr (see bottom of page) Also to be clear, (all) 11s had 16-bit virtual address and registers, but UNIBUS had 18-bit physical address, even on models without MMU where 'segment 7' forced the extra 2 bits high so interface boards would work the same as with MMU. Oct 23, 2023 at 17:59
6

I don't know about a standard, but Microsoft chose the LLP64 model for 64-bit Windows, which means that everything except pointers stays as if the processor word size were 32-bit.

Raymond Chen's blog, The Old New Thing, has an explanation for why they made that choice (which builds on a now-dead link to this MSDN page).

(In short, to make 64-bit porting feasible for pre-uint32_t code which embeds assumptions about type sizes in its definitions of things like file-formats and binary IPC, and to make it easier for 32-bit and 64-bit builds to be made from a common source during the transition period.)

...and, as Patrick Schlüter pointed out and I forgot to mention, the C standard doesn't really say much more than which types are not allowed to be smaller than which other types.

15
  • 3
    I was involved with porting application software to Itanium on Windows quite early on, and the Windows headers in the first iteration of the Platform SDK were LP64, not LLP64. The explanation Microsoft gave me was that there was lots of wizard-generated GUI code in customer companies that assumed longs and ints were the same size. It was much easier to change the size of long than to write a tool to sort out code that had been customised after generation. Sep 29, 2020 at 19:20
  • 1
    @JohnDallman: Prior to the standardization of int32_t, etc. long was the closest thing there was to a 32-bit type. While int could be 16 or 32 bits, long couldn't, so code assuming long was 32 bits would be more widely portable than code making assumptions about the size of any other type.
    – supercat
    Sep 29, 2020 at 21:54
  • 2
    @supercat my boss still insists that our coding standards prefer long to int, because he got burned back when int was only 16 bits and he won't forget. Thankfully we're using a MS compiler that still keeps long at 32 bits or we'd have a real mess. Sep 30, 2020 at 3:35
  • 1
    It's a shame that your boss chose that solution, rather than learning about type definitions, @Mark... Maybe he'll learn when long changes meaning some day to a 128-bit type? Sep 30, 2020 at 5:01
  • 1
    @CodyGray: There were two conflicting assumptions made by various programs: (1) that code needing a four-byte type can use long for that purpose, or (2) that programs needing a type that can round-trip pointers can use long for that purpose. Of those two assumptions, I would regard the latter as more dubious, since every general-purpose octet-based implementation should be expected to have a 32-bit integer type, but some implementations for 32-bit platforms might not allow pointer round-trips through it. Code needing to use 32-bit segmented mode on the 80386 without...
    – supercat
    Sep 30, 2020 at 15:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .