DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

(standards.info) System Functions

Info Catalog (standards.info) CPU Portability (standards.info) Writing C (standards.info) Internationalization
 
 Calling System Functions
 ========================
 
    C implementations differ substantially.  ANSI C reduces but does not
 eliminate the incompatibilities; meanwhile, many users wish to compile
 GNU software with pre-ANSI compilers.  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 value of `sprintf'.  It returns the number of
      characters written on some systems, but not on all systems.
 
    * `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 an ANSI 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 ANSI
      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 ANSI 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.
 
Info Catalog (standards.info) CPU Portability (standards.info) Writing C (standards.info) Internationalization
automatically generated byinfo2html