libtool: C header files

1 
1 8.1 Writing C header files
1 ==========================
1 
1 Writing portable C header files can be difficult, since they may be read
1 by different types of compilers:
1 
1 C++ compilers
1      C++ compilers require that functions be declared with full
1      prototypes, since C++ is more strongly typed than C.  C functions
1      and variables also need to be declared with the 'extern "C"'
11      directive, so that the names aren't mangled.  ⇒C++
      libraries, for other issues relevant to using C++ with libtool.
1 
1 ANSI C compilers
1      ANSI C compilers are not as strict as C++ compilers, but functions
1      should be prototyped to avoid unnecessary warnings when the header
1      file is '#include'd.
1 
1 non-ANSI C compilers
1      Non-ANSI compilers will report errors if functions are prototyped.
1 
1    These complications mean that your library interface headers must use
1 some C preprocessor magic to be usable by each of the above compilers.
1 
1    'foo.h' in the 'tests/demo' subdirectory of the libtool distribution
1 serves as an example for how to write a header file that can be safely
1 installed in a system directory.
1 
1    Here are the relevant portions of that file:
1 
1      /* BEGIN_C_DECLS should be used at the beginning of your declarations,
1         so that C++ compilers don't mangle their names.  Use END_C_DECLS at
1         the end of C declarations. */
1      #undef BEGIN_C_DECLS
1      #undef END_C_DECLS
1      #ifdef __cplusplus
1      # define BEGIN_C_DECLS extern "C" {
1      # define END_C_DECLS }
1      #else
1      # define BEGIN_C_DECLS /* empty */
1      # define END_C_DECLS /* empty */
1      #endif
1 
1      /* PARAMS is a macro used to wrap function prototypes, so that
1         compilers that don't understand ANSI C prototypes still work,
1         and ANSI C compilers can issue warnings about type mismatches. */
1      #undef PARAMS
1      #if defined __STDC__ || defined _AIX \
1              || (defined __mips && defined _SYSTYPE_SVR4) \
1              || defined WIN32 || defined __cplusplus
1      # define PARAMS(protos) protos
1      #else
1      # define PARAMS(protos) ()
1      #endif
1 
1    These macros are used in 'foo.h' as follows:
1 
1      #ifndef FOO_H
1      #define FOO_H 1
1 
1      /* The above macro definitions. */
1      #include "..."
1 
1      BEGIN_C_DECLS
1 
1      int foo PARAMS((void));
1      int hello PARAMS((void));
1 
1      END_C_DECLS
1 
1      #endif /* !FOO_H */
1 
1    Note that the '#ifndef FOO_H' prevents the body of 'foo.h' from being
1 read more than once in a given compilation.
1 
1    Also the only thing that must go outside the
1 'BEGIN_C_DECLS'/'END_C_DECLS' pair are '#include' lines.  Strictly
1 speaking it is only C symbol names that need to be protected, but your
1 header files will be more maintainable if you have a single pair of
1 these macros around the majority of the header contents.
1 
1    You should use these definitions of 'PARAMS', 'BEGIN_C_DECLS', and
1 'END_C_DECLS' into your own headers.  Then, you may use them to create
1 header files that are valid for C++, ANSI, and non-ANSI compilers(1).
1 
1    Do not be naive about writing portable code.  Following the tips
1 given above will help you miss the most obvious problems, but there are
1 definitely other subtle portability issues.  You may need to cope with
1 some of the following issues:
1 
1    * Pre-ANSI compilers do not always support the 'void *' generic
1      pointer type, and so need to use 'char *' in its place.
1 
1    * The 'const', 'inline' and 'signed' keywords are not supported by
1      some compilers, especially pre-ANSI compilers.
1 
1    * The 'long double' type is not supported by many compilers.
1 
1    ---------- Footnotes ----------
1 
1    (1) We used to recommend '__P', '__BEGIN_DECLS' and '__END_DECLS'.
1 This was bad advice since symbols (even preprocessor macro names) that
1 begin with an underscore are reserved for the use of the compiler.
1