GNU Info

Info Node: (standards.info)System Functions

(standards.info)System Functions


Next: Internationalization Prev: CPU Portability Up: Writing C
Enter node , (file) or (file)node

Calling System Functions
========================

   C implementations differ substantially.  Standard C reduces but does
not eliminate the incompatibilities; meanwhile, many GNU packages still
support pre-standard compilers because this is not hard to do.  This
chapter gives recommendations for how to use the more-or-less standard C
library functions to avoid unnecessary loss of portability.

   * Don't use the return value of `sprintf'.  It returns the number of
     characters written on some systems, but not on all systems.

   * Be aware that `vfprintf' is not always available.

   * `main' should be declared to return type `int'.  It should
     terminate either by calling `exit' or by returning the integer
     status code; make sure it cannot ever return an undefined value.

   * Don't declare system functions explicitly.

     Almost any declaration for a system function is wrong on some
     system.  To minimize conflicts, leave it to the system header
     files to declare system functions.  If the headers don't declare a
     function, let it remain undeclared.

     While it may seem unclean to use a function without declaring it,
     in practice this works fine for most system library functions on
     the systems where this really happens; thus, the disadvantage is
     only theoretical.  By contrast, actual declarations have
     frequently caused actual conflicts.

   * If you must declare a system function, don't specify the argument
     types.  Use an old-style declaration, not a Standard C prototype.
     The more you specify about the function, the more likely a
     conflict.

   * In particular, don't unconditionally declare `malloc' or `realloc'.

     Most GNU programs use those functions just once, in functions
     conventionally named `xmalloc' and `xrealloc'.  These functions
     call `malloc' and `realloc', respectively, and check the results.

     Because `xmalloc' and `xrealloc' are defined in your program, you
     can declare them in other files without any risk of type conflict.

     On most systems, `int' is the same length as a pointer; thus, the
     calls to `malloc' and `realloc' work fine.  For the few
     exceptional systems (mostly 64-bit machines), you can use
     *conditionalized* declarations of `malloc' and `realloc'--or put
     these declarations in configuration files specific to those
     systems.

   * The string functions require special treatment.  Some Unix systems
     have a header file `string.h'; others have `strings.h'.  Neither
     file name is portable.  There are two things you can do: use
     Autoconf to figure out which file to include, or don't include
     either file.

   * If you don't include either strings file, you can't get
     declarations for the string functions from the header file in the
     usual way.

     That causes less of a problem than you might think.  The newer
     standard string functions should be avoided anyway because many
     systems still don't support them.  The string functions you can
     use are these:

          strcpy   strncpy   strcat   strncat
          strlen   strcmp    strncmp
          strchr   strrchr

     The copy and concatenate functions work fine without a declaration
     as long as you don't use their values.  Using their values without
     a declaration fails on systems where the width of a pointer
     differs from the width of `int', and perhaps in other cases.  It
     is trivial to avoid using their values, so do that.

     The compare functions and `strlen' work fine without a declaration
     on most systems, possibly all the ones that GNU software runs on.
     You may find it necessary to declare them *conditionally* on a few
     systems.

     The search functions must be declared to return `char *'.  Luckily,
     there is no variation in the data type they return.  But there is
     variation in their names.  Some systems give these functions the
     names `index' and `rindex'; other systems use the names `strchr'
     and `strrchr'.  Some systems support both pairs of names, but
     neither pair works on all systems.

     You should pick a single pair of names and use it throughout your
     program.  (Nowadays, it is better to choose `strchr' and `strrchr'
     for new programs, since those are the standard names.)  Declare
     both of those names as functions returning `char *'.  On systems
     which don't support those names, define them as macros in terms of
     the other pair.  For example, here is what to put at the beginning
     of your file (or in a header) if you want to use the names
     `strchr' and `strrchr' throughout:

          #ifndef HAVE_STRCHR
          #define strchr index
          #endif
          #ifndef HAVE_STRRCHR
          #define strrchr rindex
          #endif
          
          char *strchr ();
          char *strrchr ();

   Here we assume that `HAVE_STRCHR' and `HAVE_STRRCHR' are macros
defined in systems where the corresponding functions exist.  One way to
get them properly defined is to use Autoconf.


automatically generated by info2www version 1.2.2.9