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