Portable C and
The C standard orginally defined three sizes of integer (apart
long. It was stated that
reflect the natural size for a particular machine. ANSI C added the
int be at
least 16 bits, and
long at least 32 bits.
One might therefore assume that on any 64 bit
int would be 64 bits. One would be
int is almost universally 32 bits,
save on some embedded systems on which 16 bit
might be found.
But then presumably
long will be 64 bits on any
64 bit system? It is on MacOS, Linux and all UNIX derivatives I
am aware of, but it is not on MS Windows. There it is
32 bits still, even on 64 bit platforms, just as it was on
32 bit Windows, and most 32 bit UNIXes.
The 1999 C standard added another integer data
long long. This had been in widespread use
as an extension to the 1989 standard, and the C99 standard specified
that it is at least 64 bits.
So amongst common 64 bit OSes, there are two different
implementations of the sizes of
long long. UNIX-based systems tend to use
length of 4/8/8 (in bytes, as returned by
whereas Windows uses 4/4/8. In a different terminology, 4/8/8 is
called LP64 (long and pointers 64 bit) and 4/4/8 is LLP64
(long long and pointers 64 bit).
To add to the confusion, I believe that the Cygwin environment on 64 bit Windows is LP64, just as most UNIXes are.
Hardware support for 128 bit integers is common. As one
example, the 32 bit Pentium III introduced it to the IA32
range in 1999, and all IA32 and x86_64 CPUs since have had it (the
extensions). No C compiler I am aware of
long long as 128 bit though.
C99 did introduce the
int64_t types. These were marked as optional,
required (smallest integer with at least N bits).
When it matters
The standard C library functions
ftell() use the type
long for the file
offset. So code using these functions will be unable to cope with
files of more than 2GB on Windows platforms.
Switching to using
may not be the answer. These functions return a
type, which may well avoid the 2GB limit, but they are not
guaranteed to return an integer. The only thing one can do with the
return value of
fgetpos() is pass it
fsetpos(). One cannot modify it, so one
can save one's position, but not seek to somewhere new.
Switching to using
may not be the answer. These functions return an
type, which may well avoid the 2GB limit, but they are not in any C
standard. They are part of the POSIX standard of 2001, but Windows
tends not to support POSIX.
Switching to non-standard extensions such
_ftelli64() is never
good for portability. This particular pair exist on Windows, but
Neither C99 nor C11 introduces any new functions to help here.
Trying to print pointers or file offsets by casting them
long and using a format specifier
%ld will not work well on an LLP64 system. Since C99
one can cast to
intmax_t and format with