Portability of C Functions
--------------------------
Most usual functions can either be missing, or be buggy, or be
limited on some architectures. This section tries to make an inventory
of these portability issues. By definition, this list will always
require additions. Please help us keeping it as complete as possible.
`snprintf'
The ISO C99 standard says that if the output array isn't big
enough and if no other errors occur, `snprintf' and `vsnprintf'
truncate the output and return the number of bytes that ought to
have been produced. Some older systems return the truncated
length (e.g., GNU C Library 2.0.x or IRIX 6.5), some a negative
value (e.g., earlier GNU C Library versions), and some the buffer
length without truncation (e.g., 32-bit Solaris 7). Also, some
buggy older systems ignore the length and overrun the buffer
(e.g., 64-bit Solaris 7).
`sprintf'
The ISO C standard says `sprintf' and `vsprintf' return the number
of bytes written, but on some old systems (SunOS 4 for instance)
they return the buffer pointer instead.
`sscanf'
On various old systems, e.g. HP-UX 9, `sscanf' requires that its
input string is writable (though it doesn't actually change it).
This can be a problem when using `gcc' since it normally puts
constant strings in read-only memory (Note:Incompatibilities of
GCC.). Apparently in some cases even
having format strings read-only can be a problem.
`strnlen'
AIX 4.3 provides a broken version which produces funny results:
strnlen ("foobar", 0) = 0
strnlen ("foobar", 1) = 3
strnlen ("foobar", 2) = 2
strnlen ("foobar", 3) = 1
strnlen ("foobar", 4) = 0
strnlen ("foobar", 5) = 6
strnlen ("foobar", 6) = 6
strnlen ("foobar", 7) = 6
strnlen ("foobar", 8) = 6
strnlen ("foobar", 9) = 6
`unlink'
The POSIX spec says that `unlink' causes the given files to be
removed only after there are no more open file handles for it.
Not all OS's support this behaviour though. So even on systems
that provide `unlink', you cannot portably assume it is OK to call
it on files that are open. For example, on Windows 9x and ME,
such a call would fail; on DOS it could even lead to file system
corruption, as the file might end up being written to after the OS
has removed it.
`va_copy'
The ISO C99 standard provides `va_copy' for copying `va_list'
variables. It may be available in older environments too, though
possibly as `__va_copy' (eg. `gcc' in strict C89 mode). These can
be tested with `#ifdef'. A fallback to `memcpy (&dst, &src,
sizeof(va_list))' will give maximum portability.
`va_list'
`va_list' is not necessarily just a pointer. It can be a `struct'
(eg. `gcc' on Alpha), which means `NULL' is not portable. Or it
can be an array (eg. `gcc' in some PowerPC configurations), which
means as a function parameter it can be effectively
call-by-reference and library routines might modify the value back
in the caller (eg. `vsnprintf' in the GNU C Library 2.1).
Signed `>>'
Normally the C `>>' right shift of a signed type replicates the
high bit, giving a so-called "arithmetic" shift. But care should
be taken since the ISO C standard doesn't require that behaviour.
On those few processors without a native arithmetic shift (for
instance Cray vector systems) zero bits may be shifted in, the
same as a shift of an unsigned type.