1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
(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.)
9 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 all parts of the TeX Live
tree, except some of those maintained independently.
9.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
the perhaps slightly less efficient alternative
#if !(defined HAVE_DECL_STPCPY && HAVE_DECL_STPCPY)
static inline char *stpcpy(char *dest, const char *src)
{
return strcpy(dest, src) + strlen(src);
}
#endif
in the file 'Utility.h'.
Static functions
................
Functions used in only one file should be declared 'static'; they
require no prototype except as forward declaration.
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.
9.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, and the same is true to some extent for 'libfreetype' (but,
thankfully, not for 'zlib' nowadays).
What must be avoided with 'const'
.................................
The GCC compiler warnings "assignment discards qualifiers..." and
analogous warnings for "initialization", "passing arg", or "return" must
be strenously avoided in our own code. The only exception is when they
are caused by X11 headers or macros 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.
|