So the question is could you assume or were you guaranteed that long
were enough to hold size_t
in pre C99.
Not long
, but unsigned long
.
In C89/C90, size_t
is required to be an unsigned integral type. There are exactly 4 unsigned integer types in C89/C90: unsigned char
, unsigned short
, unsigned int
, and unsigned long
. Therefore in C89/C90, size_t
can be no wider than unsigned long
, and therefore any value of type size_t
can be converted to unsigned long
without loss of information. (This applies only to unsigned long
, not to long
.)
This implicit guarantee vanished in C99, with the introduction of unsigned long long
and of extended integer types. In C99 and later, size_t
can be wider than unsigned long
. For example, a C99 implementation might have 32-bit long
and 64-bit long long
, and make size_t
an alias for unsigned long long
.
Even in C89/C90, you can rely on the guarantee only if you have a conforming C89/C90 implementation. It was common for pre-C99 compilers to provide extensions on top of the C89/C90 standard -- for example a compiler might support long long
, and might make size_t
an alias for unsigned long long
, even if the compiler didn't fully support the C99 (or C11) standard.
The question was about printf
. Keep in mind that an argument to printf
must be of an appropriate type for the format string. This:
printf("sizeof (int) = %lu\n", sizeof (int));
has undefined behavior unless size_t
happens to be an alias for unsigned long
(even if size_t
and unsigned long
happen to have the same size). You need to cast the value to the correct type:
printf("sizeof (int) = %lu\n", (unsigned long)sizeof (int));
For C99 and later, you can print size_t
values directly:
printf("sizeof (int) = %zu\n", sizeof (int));
And if like, you can test the value of __STDC_VERSION__
to determine which one to use.
(A note on editions of the C standard. The first C standard was published in 1989 by ANSI. It was republished, with extra boilerplate sections added, by ISO in 1990. So C89 and C90 are two different documents that describe the same language. The later C99 and C11 standards were published by ISO. All three ISO C standards were officially adopted by ANSI. So strictly speaking "ANSI C" should refer to ISO C11 -- but for historical reasons the phrase is still used to refer to the 1989 standard.)