File: C_STYLE_GUIDE.rst.txt

package info (click to toggle)
python-numpy 1%3A1.16.2-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 25,116 kB
  • sloc: ansic: 158,812; python: 115,039; cpp: 1,112; makefile: 502; sh: 314; f90: 289; sed: 140; fortran: 121; perl: 68
file content (220 lines) | stat: -rw-r--r-- 7,087 bytes parent folder | download
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
===================
NumPy C Style Guide
===================

The NumPy C coding conventions are based on Python PEP-0007 by Guido van
Rossum with a few added strictures. There are many C coding conventions and
it must be emphasized that the primary goal of the NumPy conventions isn't
to choose the 'best', about which there is certain to be disagreement, but
to achieve uniformity. Because the NumPy conventions are very close to
those in PEP-0007, that PEP is used as a template below with the NumPy
additions and variations in the appropriate spots.

NumPy modified PEP-0007
=======================

Introduction
------------

This document gives coding conventions for the C code comprising
the C implementation of NumPy. Note, rules are there to be broken.
Two good reasons to break a particular rule:

1. When applying the rule would make the code less readable, even
   for someone who is used to reading code that follows the rules.

2. To be consistent with surrounding code that also breaks it
   (maybe for historic reasons) -- although this is also an
   opportunity to clean up someone else's mess.


C dialect
---------

* Use ANSI/ISO standard C (the 1989 version of the standard).
  This means, amongst many other things, that all declarations
  must be at the top of a block (not necessarily at the top of
  function).

* Don't use GCC extensions (e.g. don't write multi-line strings
  without trailing backslashes). Preferably break long strings
  up onto separate lines like so::

          "blah blah"
          "blah blah"

  This will work with MSVC, which otherwise chokes on very long
  strings.

* All function declarations and definitions must use full
  prototypes (i.e. specify the types of all arguments).

* Do not use C++ style // one line comments, they aren't portable.
  Note: this will change with the proposed transition to C++.

* No compiler warnings with major compilers (gcc, VC++, a few others).
  Note: NumPy still produces compiler warnings that need to be addressed.


Code lay-out
------------

* Use 4-space indents and no tabs at all.

* No line should be longer than 80 characters.  If this and the
  previous rule together don't give you enough room to code, your code is
  too complicated, consider using subroutines.

* No line should end in whitespace.  If you think you need
  significant trailing whitespace, think again, somebody's editor might
  delete it as a matter of routine.

* Function definition style: function name in column 1, outermost
  curly braces in column 1, blank line after local variable declarations::

        static int
        extra_ivars(PyTypeObject *type, PyTypeObject *base)
        {
            int t_size = PyType_BASICSIZE(type);
            int b_size = PyType_BASICSIZE(base);

            assert(t_size >= b_size); /* type smaller than base! */
            ...
            return 1;
        }

  If the transition to C++ goes through it is possible that this form will
  be relaxed so that short class methods meant to be inlined can have the
  return type on the same line as the function name. However, that is yet to
  be determined.

* Code structure: one space between keywords like ``if``, ``for`` and
  the following left parenthesis; no spaces inside the parenthesis; braces
  around all ``if`` branches and no statements on the same line as the
  ``if``. They should be formatted as shown::

        if (mro != NULL) {
            one_line_statement;
        }
        else {
            ...
        }


        for (i = 0; i < n; i++) {
            one_line_statement;
        }


        while (isstuff) {
            dostuff;
        }


        do {
            stuff;
        } while (isstuff);


        switch (kind) {
            /* Boolean kind */
            case 'b':
                return 0;
            /* Unsigned int kind */
            case 'u':
                ...
            /* Anything else */
            default:
                return 3;
        }


* The return statement should *not* get redundant parentheses::

        return Py_None; /* correct */
        return(Py_None); /* incorrect */

* Function and macro call style: ``foo(a, b, c)``, no space before
  the open paren, no spaces inside the parens, no spaces before
  commas, one space after each comma.

* Always put spaces around assignment, Boolean and comparison
  operators.  In expressions using a lot of operators, add spaces
  around the outermost (lowest priority) operators.

* Breaking long lines: if you can, break after commas in the
  outermost argument list.  Always indent continuation lines
  appropriately, e.g., ::

        PyErr_SetString(PyExc_TypeError,
                "Oh dear, you messed up.");

  Here appropriately means at least two tabs. It isn't necessary to
  line everything up with the opening parenthesis of the function
  call.

* When you break a long expression at a binary operator, the
  operator goes at the end of the previous line, e.g., ::

        if (type > tp_dictoffset != 0 &&
                base > tp_dictoffset == 0 &&
                type > tp_dictoffset == b_size &&
                (size_t)t_size == b_size + sizeof(PyObject *)) {
            return 0;
        }

  Note that the terms in the multi-line Boolean expression are indented so
  as to make the beginning of the code block clearly visible.

* Put blank lines around functions, structure definitions, and
  major sections inside functions.

* Comments go before the code they describe. Multi-line comments should
  be like so::

        /*
         * This would be a long
         * explanatory comment.
         */

  Trailing comments should be used sparingly. Instead of ::

        if (yes) {/* Success! */

  do ::

        if (yes) {
            /* Success! */

* All functions and global variables should be declared static
  when they aren't needed outside the current compilation unit.

* Declare external functions and variables in a header file.


Naming conventions
------------------

* There has been no consistent prefix for NumPy public functions, but
  they all begin with a prefix of some sort, followed by an underscore, and
  are in camel case: ``PyArray_DescrAlignConverter``, ``NpyIter_GetIterNext``.
  In the future the names should be of the form ``Npy*_PublicFunction``,
  where the star is something appropriate.

* Public Macros should have a NPY_ prefix and then use upper case,
  for example, ``NPY_DOUBLE``.

* Private functions should be lower case with underscores, for example:
  ``array_real_get``. Single leading underscores should not be used, but
  some current function names violate that rule due to historical accident.
  Those functions should be renamed at some point.


Function documentation
----------------------

NumPy doesn't have a C function documentation standard at this time, but
needs one. Most numpy functions are not documented in the code and that
should change. One possibility is Doxygen with a plugin so that the same
NumPy style used for Python functions can also be used for documenting
C functions, see the files in doc/cdoc/.