1.. _rfc-69:
2
3=======================================================================================
4RFC 69: C/C++ Code Formatting
5=======================================================================================
6
7This document proposes and describes desired code formatting style used
8across C and C++ source code in GDAL.
9
10======== ======================================
11Author:  Kurt Schwehr
12Contact: schwehr@google.com / schwehr@gmail.com
13Started: 2017-May-04
14Status:  *Work-In-Progress*
15======== ======================================
16
17This RFC is based on `GEOS RFC
184 <https://trac.osgeo.org/geos/wiki/RFC4>`__ by Mateusz Łoskot.
19
20**TODO:** Give examples of formatting.
21
22Summary
23-------
24
25The document proposes and describes desired default code formatting
26style guidelines for GDAL programming in C and C++ languages.
27
28The goal of this document is to initiate process to reach an agreement
29for the default code formatting style.
30
31Motivation
32----------
33
34There is a need to decide on format of GDAL source code and apply such
35globally consistent format to GDAL C/C++ codebase.
36
37A uniform, codebase-wide formatting style makes reading and
38comprehending existing code easier, writing code focused on important
39aspects of new developments and more pleasant, removes burden during a
40patch or pull request code reviews and prevents `bikeshedding religious
41arguments <http://wiki.c2.com/?WhereDoTheBracesGo>`__. Even in small
42projects, contributing developers discover the problems of working
43without an agreed upon code format.
44
45The utility of such guidelines has been proven by many open source
46software projects.
47
48The scope of the proposal is specifically limited to formatting style
49guidelines. It is not an intention to develop a general coding guide
50covering other aspects of writing software like naming, etc.
51
52Proposal
53--------
54
55It is important to make effortless for developers to produce properly
56formatted code.
57
58The proposal suggests to use
59`clang-format <https://clang.llvm.org/docs/ClangFormat.html>`__ version
603.8 or higher to define C++ code formatting rules for GDAL code.
61
62The ``clang-format`` is a tool to automatically format C/C++ code, so
63that developers don't need to worry about style issues. Unlike other
64tools which use own parsers, ``clang-format`` uses the Clang tokenizer
65and supports the same C++ source code as the Clang compiler. This
66guarantees correct output is produced and offers unique features (eg.
67wrapping long lines whether of code, strings, arrays - something which
68AStyle has no way of doing).
69
70The style settings can be defined in a ``.clang-format`` configuration
71file, however to make it as easy as possible, we will use the default
72style (LLVM style?).
73
74The ``clang-format`` is straightforward to run and can support
75development workflow as standalone tool or as one of many editor
76integrations or other bespoke utilities (eg. ``git cl format``
77[Chromium]).
78
79No automation of code reformatting is proposed. It would be treating the
80symptoms, no cause: developers not following the code formatting
81standard.
82
83Although no means to enforce the default formatting style are proposed,
84currently used CI services (eg. Travis CI) may be employed as a
85post-commit safety valve - a clang-format lint failure as a compile
86break (e.g.
87`clang_format.py <https://github.com/mongodb/mongo/blob/master/buildscripts/clang_format.py>`__
88build script used by MongoDB). Alternatively, a gatekeeper may be
89installed in SVN/Git, rejecting commits with code not conforming to the
90code formatting style.
91
92Code Formatting Rules
93---------------------
94
95What code formatting rules to use?
96
97*"A mature engineers know that a standard is more important than which
98standard."* ~[MongoDB]
99
100``clang-format`` offers several defaults (eg. LLVM, Mozilla, Linux,
101Google C++ Style).
102
103The proposal recommends to use one of the base styles without any
104modification. It is possible to fine-tune the configuration, but this
105RFC aims for simplicity.
106
107The reasons are two-fold:
108
109-  make GDAL code unified with the wide spectrum of well-established
110   C/C++ projects
111-  long arguments and religious wars prevention.
112
113``.clang-format``
114~~~~~~~~~~~~~~~~~
115
116The hope is to avoid requiring a .clang-format file in the code base.
117
118``.editorconfig``
119~~~~~~~~~~~~~~~~~
120
121`EditorConfig <http://editorconfig.org/>`__ is currently in use and
122``.editorconfig`` file is provided to automatically tell popular code
123editors about the basic style settings like indentation, whitespaces and
124end-of-line markers for distinguished types of plain text files.
125
126The ``.editorconfig`` file will have to be updated to match the chosen
127``.clang-format`` settings if they are required.
128
129EOL
130~~~
131
132``clang-format`` does not enforce line endings.
133
134The EOL marker is considered to be `a part of a file encoding
135decision <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130930/090200.html>`__
136and not part of any coding style.
137
138The EOL marker can be enforced as project-wide setting controlled with
139``.gitattributes`` and ``.editorconfig``.
140
141However, it shall still be left as configurable setting in developer's
142environment of choice (eg. ``git config``) independently from the
143project-wide setting.
144
145Big Reformat
146~~~~~~~~~~~~
147
148What to do about the existing code?
149
150The proposal recommends to just do one big reformat of the codebase.
151
152While it may seem causing clutter in the repository log (eg.
153``svn blame``), if it occurs infrequently (eg. yearly) and is applied to
154the entire codebase at that time, it should not be very disruptive to
155the source code history. One way to cope with skewed history is to use
156``git blame -w`` which ignores whitespace when comparing commits.
157
158Partial application of the code formatting rules would create more work
159without delivering the full benefit [MongoDB] leading to codebase with
160different styles mixed.
161
162Branches
163^^^^^^^^
164
165Branches to run the big reformat in are:
166
167-  ``trunk``
168-  [STRIKEOUT:``branches/2.2``]
169-  [STRIKEOUT:``branches/2.1``]
170-  [STRIKEOUT:``branches/2.0``]
171
172After Big Reformat
173------------------
174
175How to work against the natural entropy in a codebase:
176
177-  It is highly recommended to use ``clang-format`` integration while
178   writing a code.
179-  Format changed code before committing or opening pull requests.
180-  If you have to commit change in code formatting, do it in separate
181   commit. Avoid commits with a mixture of code and formatting changes.
182
183   -  There is downside of history clutter in repository, but this
184      proposal states that a codebase with different styles across is
185      even worse.
186
187*"After all, every moment of time wasted on code formatting or
188discussion thereof is eliminated."* ~[MongoDB]
189
190Implementation
191--------------
192
193Set up Travis CI "style safety valve" build dedicated to run
194clang-format lint based on the approach used in ``​clang_format.py``
195script by MongoDB.
196
197Miscellaneous
198-------------
199
200Those who build GDAL with GCC 6+ may appreciate consistent code format
201style as it will help to avoid some dozens of the `new compiler
202warnings <https://developers.redhat.com/blog/2016/02/26/gcc-6-wmisleading-indentation-vs-goto-fail/>`__:
203
204::
205
206   src/geom/Polygon.cpp: In member function ‘virtual int geos::geom::Polygon::getCoordinateDimension() const’:
207   src/geom/Polygon.cpp:154:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
208        if( shell != NULL )
209        ^~
210   src/geom/Polygon.cpp:157:2: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘if’
211     size_t nholes=holes->size();
212     ^~~~~~
213
214References
215----------
216
217-  [MongoDB] Succeeding With ClangFormat: `Part
218   1 <https://engineering.mongodb.com/post/succeeding-with-clangformat-part-1-pitfalls-and-planning/>`__,
219   `Part
220   2 <https://engineering.mongodb.com/post/succeeding-with-clangformat-part-2-the-big-reformat/>`__,
221   `Part
222   3 <https://engineering.mongodb.com/post/succeeding-with-clangformat-part-3-persisting-the-change/>`__
223-  [Chromium] `Using clang-format on Chromium C++
224   Code <https://chromium.googlesource.com/chromium/src/+/master/docs/clang_format.md>`__
225-  `https://clangformat.com <https://clangformat.com>`__ -
226   ``clang-format`` interactive guide and builder
227-  `https://zed0.co.uk/clang-format-configurator/ <https://zed0.co.uk/clang-format-configurator/>`__
228-  `https://trac.osgeo.org/geos/wiki/RFC4 <https://trac.osgeo.org/geos/wiki/RFC4>`__
229