Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 1 | .. _chapter-style: |
| 2 | |
| 3 | .. default-domain:: cpp |
| 4 | |
| 5 | .. highlight:: sh |
| 6 | |
| 7 | =========================== |
| 8 | Style Guide and Conventions |
| 9 | =========================== |
| 10 | |
| 11 | --------- |
| 12 | C++ style |
| 13 | --------- |
| 14 | |
| 15 | The Pigweed C++ style guide is closely based on Google's external C++ Style |
| 16 | Guide, which is found on the web at |
| 17 | https://google.github.io/styleguide/cppguide.html. The Google C++ Style Guide |
| 18 | applies to Pigweed except as described in this document. |
| 19 | |
| 20 | The Pigweed style guide only applies to Pigweed itself. It does not apply to |
Alexei Frolov | 44d5473 | 2020-01-10 14:45:43 -0800 | [diff] [blame] | 21 | projects that use Pigweed or to the third-party code included with Pigweed. |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 22 | Non-Pigweed code is free to use features restricted by Pigweed, such as dynamic |
| 23 | memory allocation and the entirety of the C++ Standard Library. |
| 24 | |
| 25 | Recommendations in the :doc:`embedded_cpp_guide` are considered part of the |
| 26 | Pigweed style guide, but are separated out since it covers more general |
| 27 | embedded development beyond just C++ style. |
| 28 | |
| 29 | Automatic formatting |
| 30 | ==================== |
| 31 | Pigweed uses `clang-format <https://clang.llvm.org/docs/ClangFormat.html>`_ to |
| 32 | automatically format Pigweed source code. A ``.clang-format`` configuration is |
| 33 | provided with the Pigweed repository. |
| 34 | |
| 35 | Automatic formatting is essential to facilitate large-scale, automated changes |
| 36 | in Pigweed. Therefore, all code in Pigweed is expected to be formatted with |
| 37 | ``clang-format`` prior to submission. Existing code may be reformatted at any |
| 38 | time. |
| 39 | |
| 40 | If ``clang-format`` formats code in an undesirable or incorrect way, it can be |
| 41 | disabled for the affected lines by adding ``// clang-format off``. |
| 42 | ``clang-format`` must then be re-enabled with a ``// clang-format on`` comment. |
| 43 | |
| 44 | .. code-block:: cpp |
| 45 | |
| 46 | // clang-format off |
Alexei Frolov | 44d5473 | 2020-01-10 14:45:43 -0800 | [diff] [blame] | 47 | constexpr int kMyMatrix[] = { |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 48 | 100, 23, 0, |
| 49 | 0, 542, 38, |
| 50 | 1, 2, 201, |
| 51 | }; |
| 52 | // clang-format on |
| 53 | |
| 54 | C Standard Library |
| 55 | ================== |
| 56 | In C++ headers, always use the C++ versions of C Standard Library headers (e.g. |
| 57 | ``<cstdlib>`` instead of ``<stdlib.h>``). If the header is used by both C and |
| 58 | C++ code, only the C header should be used. |
| 59 | |
| 60 | In C++ code, it is preferred to use C functions from the ``std`` namespace. For |
| 61 | example, use ``std::memcpy`` instead of ``memcpy``. The C++ standard does not |
| 62 | require the global namespace versions of the functions to be provided. Using |
| 63 | ``std::`` is more consistent with the C++ Standard Library and makes it easier |
| 64 | to distinguish Pigweed functions from library functions. |
| 65 | |
| 66 | Within core Pigweed, do not use C standard library functions that allocate |
| 67 | memory, such as ``std::malloc``. There are exceptions to this for when dynamic |
| 68 | allocation is enabled for a system; Pigweed modules are allowed to add extra |
| 69 | functionality when a heap is present; but this must be optional. |
| 70 | |
| 71 | C++ Standard Library |
| 72 | ==================== |
| 73 | Much of the C++ Standard Library is not a good fit for embedded software. Many |
| 74 | of the classes and functions were not designed with the RAM, flash, and |
| 75 | performance constraints of a microcontroller in mind. For example, simply |
| 76 | adding the line ``#include <iostream>`` can increase the binary size by 150 KB! |
Alexei Frolov | 44d5473 | 2020-01-10 14:45:43 -0800 | [diff] [blame] | 77 | This is larger than many microcontrollers' entire internal storage. |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 78 | |
| 79 | However, with appropriate caution, a limited set of standard C++ libraries can |
| 80 | be used to great effect. Developers can leverage familiar, well-tested |
| 81 | abstractions instead of writing their own. C++ library algorithms and classes |
| 82 | can give equivalent or better performance than hand-written C code. |
| 83 | |
| 84 | A limited subset of the C++ Standard Library is permitted in Pigweed. To keep |
| 85 | Pigweed small, flexible, and portable, functions that allocate dynamic memory |
| 86 | must be avoided. Care must be exercised when using multiple instantiations of a |
| 87 | template function, which can lead to code bloat. |
| 88 | |
| 89 | The following C++ Standard Library headers are always permitted: |
| 90 | |
| 91 | * ``<array>`` |
| 92 | * ``<complex>`` |
| 93 | * ``<initializer_list>`` |
| 94 | * ``<iterator>`` |
| 95 | * ``<limits>`` |
| 96 | * ``<optional>`` |
| 97 | * ``<random>`` |
| 98 | * ``<ratio>`` |
| 99 | * ``<span>`` |
| 100 | * ``<string_view>`` |
| 101 | * ``<tuple>`` |
| 102 | * ``<type_traits>`` |
| 103 | * ``<utility>`` |
| 104 | * ``<variant>`` |
| 105 | * C Standard Library headers (``<c*>``) |
| 106 | |
| 107 | With caution, parts of the following headers can be used: |
| 108 | |
| 109 | * ``<algorithm>`` -- be wary of potential memory allocation |
| 110 | * ``<atomic>`` -- not all MCUs natively support atomic operations |
| 111 | * ``<bitset>`` -- conversions to or from strings are disallowed |
| 112 | * ``<functional>`` -- do **not** use ``std::function`` |
| 113 | * ``<new>`` -- for placement new |
| 114 | * ``<numeric>`` -- be wary of code size with multiple template instantiations |
| 115 | |
| 116 | Never use any of these headers: |
| 117 | |
| 118 | * Dynamic containers (``<list>``, ``<map>``, ``<set>``, ``<vector>``, etc.) |
| 119 | * Streams (``<iostream>``, ``<ostream>``, ``<fstream>``, etc.) |
| 120 | * ``<exception>`` |
| 121 | * ``<future>``, ``<mutex>``, ``<thread>`` |
| 122 | * ``<memory>`` |
| 123 | * ``<regex>`` |
| 124 | * ``<scoped_allocator>`` |
| 125 | * ``<sstream>`` |
| 126 | * ``<stdexcept>`` |
| 127 | * ``<string>`` |
| 128 | * ``<valarray>`` |
| 129 | |
| 130 | Headers not listed here should be carefully evaluated before they are used. |
| 131 | |
| 132 | These restrictions do not apply to third party code or to projects that use |
| 133 | Pigweed. |
| 134 | |
| 135 | Combining C and C++ |
| 136 | =================== |
| 137 | Prefer to write C++ code over C code, using ``extern "C"`` for symbols that must |
| 138 | have C linkage. ``extern "C"`` functions should be defined within C++ |
| 139 | namespaces to simplify referring to other code. |
| 140 | |
| 141 | C++ functions with no parameters do not include ``void`` in the parameter list. |
| 142 | C functions with no parameters must include ``void``. |
| 143 | |
| 144 | .. code-block:: cpp |
| 145 | |
| 146 | namespace pw { |
| 147 | |
| 148 | bool ThisIsACppFunction() { return true; } |
| 149 | |
| 150 | extern "C" int pw_ThisIsACFunction(void) { return -1; } |
| 151 | |
| 152 | extern "C" { |
| 153 | |
| 154 | int pw_ThisIsAlsoACFunction(void) { |
| 155 | return ThisIsACppFunction() ? 100 : 0; |
| 156 | } |
| 157 | |
| 158 | } // extern "C" |
| 159 | |
| 160 | } // namespace pw |
| 161 | |
| 162 | Comments |
| 163 | ======== |
| 164 | Prefer C++-style (``//``) comments over C-style commments (``/* */``). C-style |
| 165 | comments should only be used for inline comments. |
| 166 | |
| 167 | .. code-block:: cpp |
| 168 | |
| 169 | // Use C++-style comments, except where C-style comments are necessary. |
| 170 | // This returns a random number using an algorithm I found on the internet. |
| 171 | #define RANDOM_NUMBER() [] { \ |
| 172 | return 4; /* chosen by fair dice roll */ \ |
| 173 | }() |
| 174 | |
| 175 | Indent code in comments with two additional spaces, making a total of three |
| 176 | spaces after the ``//``. All code blocks must begin and end with an empty |
Alexei Frolov | 44d5473 | 2020-01-10 14:45:43 -0800 | [diff] [blame] | 177 | comment line, even if the blank comment line is the last line in the block. |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 178 | |
| 179 | .. code-block:: cpp |
| 180 | |
| 181 | // Here is an example of code in comments. |
| 182 | // |
| 183 | // int indentation_spaces = 2; |
| 184 | // int total_spaces = 3; |
| 185 | // |
| 186 | // engine_1.thrust = RANDOM_NUMBER() * indentation_spaces + total_spaces; |
| 187 | // |
| 188 | bool SomeFunction(); |
| 189 | |
| 190 | Control statements |
| 191 | ================== |
| 192 | All loops and conditional statements must use braces. |
| 193 | |
| 194 | The syntax ``while (true)`` if preferred over ``for (;;)`` for infinite loops. |
| 195 | |
| 196 | Include guards |
| 197 | ============== |
| 198 | The first non-comment line of every header file must be ``#pragma once``. Do |
| 199 | not use traditional macro include guards. The ``#pragma once`` should come |
| 200 | directly after the Pigweed copyright block, with no blank line, followed by a |
| 201 | blank, like this: |
| 202 | |
| 203 | .. code-block:: cpp |
| 204 | |
| 205 | // Copyright 2019 The Pigweed Authors |
| 206 | // |
| 207 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
Wyatt Hepler | 1a96094 | 2019-11-26 14:13:38 -0800 | [diff] [blame] | 208 | // use this file except in compliance with the License. You may obtain a copy of |
| 209 | // the License at |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 210 | // |
| 211 | // https://www.apache.org/licenses/LICENSE-2.0 |
| 212 | // |
| 213 | // Unless required by applicable law or agreed to in writing, software |
| 214 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 215 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
Wyatt Hepler | 1a96094 | 2019-11-26 14:13:38 -0800 | [diff] [blame] | 216 | // License for the specific language governing permissions and limitations under |
| 217 | // the License. |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 218 | #pragma once |
| 219 | |
| 220 | // Header file-level comment goes here... |
| 221 | |
| 222 | Memory allocation |
| 223 | ================= |
| 224 | Dynamic memory allocation can be problematic. Heap allocations and deallocations |
| 225 | occupy valuable CPU cycles. Memory usage becomes nondeterministic, which can |
| 226 | result in a system crashing without a clear culprit. |
| 227 | |
| 228 | To keep Pigweed portable, core Pigweed code is not permitted to dynamically |
| 229 | (heap) allocate memory, such as with ``malloc`` or ``new``. All memory should be |
| 230 | allocated with automatic (stack) or static (global) storage duration. Pigweed |
| 231 | must not use C++ libraries that use dynamic allocation. |
| 232 | |
| 233 | Projects that use Pigweed are free to use dynamic allocation, provided they |
| 234 | have selected a target that enables the heap. |
| 235 | |
| 236 | Naming |
| 237 | ====== |
| 238 | Entities shall be named according to the `Google style guide |
| 239 | <https://google.github.io/styleguide/cppguide.html>`_, with the following |
| 240 | additional requirements. |
| 241 | |
| 242 | **C++ code** |
| 243 | * All Pigweed C++ code must be in the ``pw`` namespace. Namespaces for |
| 244 | modules should be nested under ``pw``. For example, |
| 245 | ``pw::string::Format()``. |
| 246 | * Whenever possible, private code should be in a source (.cc) file and placed |
| 247 | in anonymous namespace nested under ``pw``. |
| 248 | * If private code must be exposed in a header file, it must be in a namespace |
| 249 | nested under ``pw``. The namespace may be named for its subsystem or use a |
| 250 | name that designates it as private, such as ``internal``. |
| 251 | |
| 252 | **C code** |
| 253 | * Public names used by C code must be prefixed with ``pw_``. |
| 254 | * If private code must be exposed in a header, private names used by C code |
| 255 | must be prefixed with ``_pw_``. |
| 256 | * Avoid writing C source (.c) files in Pigweed. Prefer to write C++ code with |
| 257 | C linkage using ``extern "C"``. Within C source, private C functions and |
| 258 | variables must be named with the ``_pw_`` prefix and should be declared |
| 259 | ``static`` whenever possible; for example, ``_pw__MyPrivateFunction``. |
| 260 | * The C prefix rules apply to |
| 261 | |
| 262 | * C functions (``int pw_FunctionName(void);``), |
| 263 | * variables used by C code (``int pw_variable_name;``), |
| 264 | * constant variables used by C code (``int pw_kConstantName;``), and |
| 265 | * structs used by C code (``typedef struct {} pw_StructName;``). |
| 266 | |
| 267 | The prefix does not apply to struct members, which use normal Google style. |
| 268 | |
| 269 | **Preprocessor macros** |
| 270 | * Public Pigweed macros must be prefixed with ``PW_``. |
| 271 | * Private Pigweed macros must be prefixed with ``_PW_``. |
| 272 | |
| 273 | **Example** |
| 274 | |
| 275 | .. code-block:: cpp |
| 276 | |
| 277 | namespace pw { |
| 278 | namespace nested_namespace { |
| 279 | |
| 280 | // C++ names (types, variables, functions) must be in the pw namespace. |
| 281 | // They are named according to the Google style guide. |
| 282 | constexpr int kGlobalConstant = 123; |
| 283 | |
| 284 | // Prefer using functions over extern global variables. |
| 285 | extern int global_variable; |
| 286 | |
| 287 | class Class {}; |
| 288 | |
| 289 | void Function(); |
| 290 | |
| 291 | extern "C" { |
| 292 | |
| 293 | // Public Pigweed code used from C must be prefixed with pw_. |
| 294 | extern const int pw_kGlobalConstant; |
| 295 | |
| 296 | extern int pw_global_variable; |
| 297 | |
| 298 | void pw_Function(void); |
| 299 | |
| 300 | typedef struct { |
| 301 | int member_variable; |
| 302 | } pw_Struct; |
| 303 | |
| 304 | // Private Pigweed code used from C must be prefixed with _pw_. |
| 305 | extern const int _pw_kPrivateGlobalConstant; |
| 306 | |
| 307 | extern int _pw_private_global_variable; |
| 308 | |
| 309 | void _pw_PrivateFunction(void); |
| 310 | |
| 311 | typedef struct { |
| 312 | int member_variable; |
| 313 | } _pw_PrivateStruct; |
| 314 | |
| 315 | } // extern "C" |
| 316 | |
| 317 | // Public macros must be prefixed with PW_. |
| 318 | #define PW_PUBLIC_MACRO(arg) arg |
| 319 | |
| 320 | // Private macros must be prefixed with _PW_. |
| 321 | #define _PW_PRIVATE_MACRO(arg) arg |
| 322 | |
| 323 | } // namespace nested_namespace |
| 324 | } // namespace pw |
| 325 | |
| 326 | Namespace scope formatting |
| 327 | ========================== |
| 328 | All non-indented blocks (namespaces, ``extern "C"`` blocks, and preprocessor |
| 329 | conditionals) must have a comment on their closing line with the |
| 330 | contents of the starting line. |
| 331 | |
| 332 | All nested namespaces should be declared together with no blank lines between |
| 333 | them. |
| 334 | |
| 335 | .. code-block:: cpp |
| 336 | |
| 337 | #include "some/header.h" |
| 338 | |
| 339 | namespace pw::nested { |
| 340 | namespace { |
| 341 | |
| 342 | constexpr int kAnonConstantGoesHere = 0; |
| 343 | |
| 344 | } // namespace |
| 345 | |
| 346 | namespace other { |
| 347 | |
| 348 | const char* SomeClass::yes = "no"; |
| 349 | |
| 350 | bool ThisIsAFunction() { |
| 351 | #if PW_CONFIG_IS_SET |
| 352 | return true; |
| 353 | #else |
| 354 | return false; |
| 355 | #endif // PW_CONFIG_IS_SET |
| 356 | } |
| 357 | |
| 358 | extern "C" { |
| 359 | |
| 360 | const int pw_kSomeConstant = 10; |
| 361 | int pw_some_global_variable = 600; |
| 362 | |
| 363 | void pw_CFunction() { ... } |
| 364 | |
| 365 | } // extern "C" |
| 366 | |
| 367 | } // namespace |
| 368 | } // namespace pw::nested |
| 369 | |
| 370 | Pointers and references |
| 371 | ======================= |
| 372 | For pointer and reference types, place the asterisk or ampersand next to the |
| 373 | type. |
| 374 | |
| 375 | .. code-block:: cpp |
| 376 | |
| 377 | int* const number = &that_thing; |
| 378 | constexpr const char* kString = "theory!" |
| 379 | |
| 380 | bool FindTheOneRing(const Region& where_to_look) { ... } |
| 381 | |
| 382 | Prefer storing references over storing pointers. Pointers are required when the |
| 383 | pointer can change its target or may be ``nullptr``. Otherwise, a reference or |
| 384 | const reference should be used. In accordance with the Google C++ style guide, |
| 385 | only const references are permitted as function arguments; pointers must be used |
| 386 | in place of mutable references when passed as function arguments. |
| 387 | |
| 388 | Preprocessor macros |
| 389 | =================== |
| 390 | Macros should only be used when they significantly improve upon the C++ code |
| 391 | they replace. Macros should make code more readable, robust, and safe, or |
| 392 | provide features not possible with standard C++, such as stringification, line |
| 393 | number capturing, or conditional compilation. When possible, use C++ constructs |
| 394 | like constexpr variables in place of macros. Never use macros as constants, |
| 395 | except when a string literal is needed or the value must be used by C code. |
| 396 | |
| 397 | When macros are needed, the macros should be accompanied with extensive tests |
| 398 | to ensure the macros are hard to use wrong. |
| 399 | |
| 400 | Stand-alone statement macros |
| 401 | ---------------------------- |
| 402 | Macros that are standalone statements must require the caller to terminate the |
Alexei Frolov | 44d5473 | 2020-01-10 14:45:43 -0800 | [diff] [blame] | 403 | macro invocation with a semicolon. For example, the following does *not* conform |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 404 | to Pigweed's macro style: |
| 405 | |
| 406 | .. code-block:: cpp |
| 407 | |
| 408 | // BAD! Definition has built-in semicolon. |
| 409 | #define PW_LOG_IF_BAD(mj) \ |
| 410 | CallSomeFunction(mj); |
| 411 | |
| 412 | // BAD! Compiles without error; semicolon is missing. |
Alexei Frolov | 44d5473 | 2020-01-10 14:45:43 -0800 | [diff] [blame] | 413 | PW_LOG_IF_BAD("foo") |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 414 | |
| 415 | Here's how to do this instead: |
| 416 | |
| 417 | .. code-block:: cpp |
| 418 | |
| 419 | // GOOD; requires semicolon to compile. |
| 420 | #define PW_LOG_IF_BAD(mj) \ |
| 421 | CallSomeFunction(mj) |
| 422 | |
| 423 | // GOOD; fails to compile due to lacking semicolon. |
Alexei Frolov | 44d5473 | 2020-01-10 14:45:43 -0800 | [diff] [blame] | 424 | PW_LOG_IF_BAD("foo") |
Keir Mierle | 2c1e56b | 2019-11-15 16:32:11 -0800 | [diff] [blame] | 425 | |
| 426 | For macros in function scope that do not already require a semicolon, the |
| 427 | contents can be placed in a ``do { ... } while (0)`` loop. |
| 428 | |
| 429 | .. code-block:: cpp |
| 430 | |
| 431 | #define PW_LOG_IF_BAD(mj) \ |
| 432 | do { \ |
| 433 | if (mj.Bad()) { \ |
| 434 | Log(#mj " is bad") \ |
| 435 | } \ |
| 436 | } while (0) |
| 437 | |
| 438 | Standalone macros at global scope that do not already require a semicolon can |
| 439 | add a ``static_assert`` or throwaway struct declaration statement as their |
| 440 | last line. |
| 441 | |
| 442 | .. code-block:: cpp |
| 443 | |
| 444 | #define PW_NEAT_THING(thing) \ |
| 445 | bool IsNeat_##thing() { return true; } \ |
| 446 | static_assert(true, "Macros must be terminated with a semicolon") |
| 447 | |
| 448 | Private macros in public headers |
| 449 | -------------------------------- |
| 450 | Private macros in public headers must be prefixed with ``_PW_``, even if they |
| 451 | are undefined after use; this prevents collisions with downstream users. For |
| 452 | example: |
| 453 | |
| 454 | .. code-block:: cpp |
| 455 | |
| 456 | #define _PW_MY_SPECIAL_MACRO(op) ... |
| 457 | ... |
| 458 | // Code that uses _PW_MY_SPECIAL_MACRO() |
| 459 | ... |
| 460 | #undef _PW_MY_SPECIAL_MACRO |
| 461 | |
| 462 | Macros in private implementation files (.cc) |
| 463 | -------------------------------------------- |
| 464 | Macros within .cc files that should only used within one file should be |
| 465 | undefined after their last use; for example: |
| 466 | |
| 467 | .. code-block:: cpp |
| 468 | |
| 469 | #define DEFINE_OPERATOR(op) \ |
| 470 | T operator ## op(T x, T y) { return x op y; } \ |
| 471 | static_assert(true, "Macros must be terminated with a semicolon") \ |
| 472 | |
| 473 | DEFINE_OPERATOR(+); |
| 474 | DEFINE_OPERATOR(-); |
| 475 | DEFINE_OPERATOR(/); |
| 476 | DEFINE_OPERATOR(*); |
| 477 | |
| 478 | #undef DEFINE_OPERATOR |
| 479 | |
| 480 | Preprocessor conditional statements |
| 481 | =================================== |
| 482 | When using macros for conditional compilation, prefer to use ``#if`` over |
| 483 | ``#ifdef``. This checks the value of the macro rather than whether it exists. |
| 484 | |
| 485 | * ``#if`` handles undefined macros equivalently to ``#ifdef``. Undefined |
| 486 | macros expand to 0 in preprocessor conditional statements. |
| 487 | * ``#if`` evaluates false for macros defined as 0, while ``#ifdef`` evaluates |
| 488 | true. |
| 489 | * Macros defined using compiler flags have a default value of 1 in GCC and |
| 490 | Clang, so they work equivalently for ``#if`` and ``#ifdef``. |
| 491 | * Macros defined to an empty statement cause compile-time errors in ``#if`` |
| 492 | statements, which avoids ambiguity about how the macro should be used. |
| 493 | |
| 494 | All ``#endif`` statements should be commented with the expression from their |
| 495 | corresponding ``#if``. Do not indent within preprocessor conditional statements. |
| 496 | |
| 497 | .. code-block:: cpp |
| 498 | |
| 499 | #if USE_64_BIT_WORD |
| 500 | using Word = uint64_t; |
| 501 | #else |
| 502 | using Word = uint32_t; |
| 503 | #endif // USE_64_BIT_WORD |
| 504 | |
| 505 | Unsigned integers |
| 506 | ================= |
| 507 | Unsigned integers are permitted in Pigweed. Aim for consistency with existing |
| 508 | code and the C++ Standard Library. Be very careful mixing signed and unsigned |
| 509 | integers. |
| 510 | |
| 511 | ------------ |
| 512 | Python style |
| 513 | ------------ |
| 514 | Pigweed uses the standard Python style: PEP8, which is available on the web at |
| 515 | https://www.python.org/dev/peps/pep-0008/. All Pigweed Python code should pass |
| 516 | ``yapf`` when configured for PEP8 style. |
| 517 | |
Wyatt Hepler | ab4eb7a | 2020-01-08 18:04:31 -0800 | [diff] [blame] | 518 | Python 3 |
| 519 | ======== |
| 520 | Pigweed uses Python 3. Some modules may offer limited support for Python 2, but |
| 521 | Python 3.6 or newer is required for most Pigweed code. |