Search code examples
clanguage-lawyerc89

Was `long` guaranteed to be as wide as `size_t`


When looking for evidence of unsigned long being enough to hold size_t for the purpose of being argument to printf I ran into two fact(oid)s.

First there's this answer stating that long is indeed not guaranteed to be large enough for size_t. On the other hand I saw this answer suggesting to use printf("%lu", (unsigned long)x) in pre C99, x being of size_t.

So the question is could you assume or were you guaranteed that long were enough to hold size_t in pre C99. The other question is whether there exists any guarantee that size_t would fit in any of the other standardized integer types (except the obvious exceptions like ssize_t, ptrdiff_t and such).


Solution

  • There is no such guarantee.

    While it is common for implementation to have same size for long and size_t, it is not always the case. As put in the comments Windows 64-bit have different size for long and size_t.

    Also notice that the minimum value of SIZE_MAX for an implementation is 65535 while the minimum value of ULONG_MAX is 4294967295 (2147483647 for LONG_MAX). (Note that SIZE_MAX appeared with C99.) It means that size_t is guaranteed to be at least 16-bit but unsigned long / long are guaranteed to be at least 32-bit.

    EDIT: Question has changed a little bit after this answer... So:

    So the question is could you assume or were you guaranteed that long were enough to hold size_t in pre C99.

    There is no such guarantee even in C89. long can be 32-bit and size_t 64-bit. (See C89 example with MSVC in Windows 64-bit above.)

    The other question is whether there exists any guarantee that size_t would fit in any of the other standardized integer types (except the obvious exceptions like ssize_t, ptrdiff_t and such).

    Again there is no such guarantee by the Standard. size_t is an alias for another standard unsigned integer type (and it cannot be an extended integer type as C89 does not have extended integer types).