Next: Particular Functions, Up: Library 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.
exitexit returns int?
This is because exit predates void, and there was a long
tradition of it returning int.
putenvputenv puts the given string directly in
environ, but some systems make a copy of it instead (eg.
glibc 2.0, or BSD). And when a copy is made, unsetenv might
not free it, causing a memory leak (eg. FreeBSD 4).
POSIX specifies that putenv("FOO") removes `FOO' from the
environment, but on some systems (eg. FreeBSD 4) this is not the
case and instead unsetenv must be used.
On MINGW, a call putenv("FOO=") removes `FOO' from the
environment, rather than inserting it with an empty value.
signal handlersignal takes a handler function with a return type of
void, but some old systems required int instead. Any
actual int value returned is not used, this is only a
difference in the function prototype demanded.
All systems we know of in current use take void. Presumably
int was to support K&R C, where of course void is not
available. AC_TYPE_SIGNAL (see Particular Types) can be
used to establish the correct type in all cases.
snprintfsnprintf 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).
sprintfsprintf and vsprintf return the
number of bytes written, but on some old systems (SunOS 4 for
instance) they return the buffer pointer instead.
sscanfsscanf requires that its
input string be 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
(see Incompatibilities of GCC). Apparently in some cases even
having format strings read-only can be a problem.
strnlen 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
sysconf_SC_PAGESIZE is standard, but some older systems (eg. HP-UX
9) have _SC_PAGE_SIZE instead. This can be tested with
#ifdef.
unlinkunlink causes the given file to be
removed only after there are no more open file handles for it. Not all
OS's support this behavior 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.
unsetenvunsetenv is not available, but a variable `FOO'
can be removed with a call putenv("FOO="), as described under
putenv above.
va_copyva_copy for copying
va_list variables. It may be available in older environments
too, though possibly as __va_copy (e.g., 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_listva_list is not necessarily just a pointer. It can be a
struct (e.g., gcc on Alpha), which means NULL is
not portable. Or it can be an array (e.g., 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 (e.g., vsnprintf in the GNU C Library
2.1).
>>>> 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 behavior. 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.