(This file was generated by makeinfo and splitinfo.gawk.) (Released under the old-style GNU documentation license; see sources or other output files for full text.) 8 Coding conventions ******************** Ideally, building all of TeX Live with '--enable-compiler-warnings=max' should produce no (GCC) compiler warnings at all. In spite of considerable efforts into that direction we are still far from that goal and there are reasons that we may never fully reach it. Below are some rules about declarations of functions or variables and the use of 'const'. These rules should be applied to the code maintained in the TeX Live tree and for other packages whose maintainers are willing to accept patches. 8.1 Declarations and definitions ================================ C standards ........... The TeX Live build system no longer supports pre-ANSI C compilers. Thus all function prototypes and definitions must conform to the ANSI C standard (including 'void' in the declaration of C functions with no parameters). On the other hand, TL is built for a wide variety of systems, not all of which support the C99 standard. Therefore using C99 features should be avoided if that can easily be done. In particular, C code must not contain declarations after statements or C++-style comments. If some C99 (or later) constructs must be used, the module should verify that they are available and otherwise provide an alternative. For example, the module 'texk/chktex' uses the C99 function 'stpcpy()' that may or may not be available on a particular system. It uses 'AC_CHECK_DECLS([stpcpy])' in 'configure.ac' to test this, and provides a perhaps less efficient alternative (in the file 'Utility.h'): #if !(defined HAVE_DECL_STPCPY && HAVE_DECL_STPCPY) static inline char *stpcpy(char *dest, const char *src) { return strcpy(dest, src) + strlen(src); } #endif Static functions ................ Functions used in only one file should be declared 'static'; they require no prototype except in forward declarations. Extern functions ................ Functions not declared 'static', usually because they are used in several files, require an ('extern') prototype in exactly one header file, which is included in the file defining the function and in all files using that function--this is the only way to guarantee consistency between definition and use. There should be no 'extern' declarations sprinkled throughout the C code (with or without comments as to where that function is defined). Variable declarations ..................... The declaration of global variables follows analogous rules: they are either declared 'static' if used in only one file or declared 'extern' in exactly one header and instantiated in exactly one file. 8.2 Const ========= The 'const' feature of C is valuable, but easy to mis-use. Function parameters ................... Ideally, a function parameter not modified by the function should be declared as 'const'. This is important in particular for strings ('char*') because the actual arguments are often string literals. It is perfectly legitimate and safe to use a type 'char*' value for a type 'const char*' variable (in an assignment, as initializer, as function argument, or as return value). It is equally safe to use a type 'char**' value for a type 'const char*const*' variable, but not for a type 'const char**' variable since that might cause modification of a quantity supposed to be constant. Getting all 'const' qualifiers right can get quite involved but can almost always be done. There are only a couple notable exceptions: the X11 headers are full of declarations that ought to use 'const' but do not; at one time, 'libfreetype' also did not fully specify 'const', but this has not been checked recently. What must be avoided with 'const' ................................. The GCC compiler warnings "assignment discards qualifiers..." and analogous warnings for "initialization", "passing arg", or "return" must be strenuously avoided in our own code. The only exception is when they are caused by X11 declarations or other third party code. What should be avoided with 'const' ................................... A type cast, e.g., from 'const char*' to 'char*' does not solve any problems; depending on warning options, it may only hide them. Therefore such casts should be avoided whenever possible and otherwise must be carefully analyzed to make sure that they cannot cause the modification of quantities supposed to be constant.