1.. _docs-pw-style-cpp: 2 3========= 4C++ style 5========= 6The Pigweed C++ style guide is closely based on Google's external C++ Style 7Guide, which is found on the web at 8https://google.github.io/styleguide/cppguide.html. The Google C++ Style Guide 9applies to Pigweed except as described in this document. 10 11The Pigweed style guide only applies to Pigweed itself. It does not apply to 12projects that use Pigweed or to the third-party code included with Pigweed. 13Non-Pigweed code is free to use features restricted by Pigweed, such as dynamic 14memory allocation and the entirety of the C++ Standard Library. 15 16Recommendations in the :ref:`docs-embedded-cpp` are considered part of the 17Pigweed style guide, but are separated out since it covers more general 18embedded development beyond just C++ style. 19 20C++ standard 21============ 22All Pigweed C++ code must compile with ``-std=c++17`` in Clang and GCC. C++20 23features may be used as long as the code still compiles unmodified with C++17. 24See ``pw_polyfill/language_feature_macros.h`` for macros that provide C++20 25features when supported. 26 27Compiler extensions should not be used unless wrapped in a macro or properly 28guarded in the preprocessor. See ``pw_processor/compiler.h`` for macros that 29wrap compiler-specific features. 30 31Automatic formatting 32==================== 33Pigweed uses `clang-format <https://clang.llvm.org/docs/ClangFormat.html>`_ to 34automatically format Pigweed source code. A ``.clang-format`` configuration is 35provided with the Pigweed repository. Within an upstream Pigweed environment, the 36`pw format` tool can be used to automatically format code. 37 38Automatic formatting is essential to facilitate large-scale, automated changes 39in Pigweed. Therefore, all code in Pigweed is expected to be formatted with 40``clang-format`` prior to submission. Existing code may be reformatted at any 41time. 42 43If ``clang-format`` formats code in an undesirable or incorrect way, it can be 44disabled for the affected lines by adding ``// clang-format off``. 45``clang-format`` must then be re-enabled with a ``// clang-format on`` comment. 46 47.. code-block:: cpp 48 49 // clang-format off 50 constexpr int kMyMatrix[] = { 51 100, 23, 0, 52 0, 542, 38, 53 1, 2, 201, 54 }; 55 // clang-format on 56 57C Standard Library 58================== 59In C++ headers, always use the C++ versions of C Standard Library headers (e.g. 60``<cstdlib>`` instead of ``<stdlib.h>``). If the header is used by both C and 61C++ code, only the C header should be used. 62 63In C++ code, it is preferred to use C functions from the ``std`` namespace. For 64example, use ``std::memcpy`` instead of ``memcpy``. The C++ standard does not 65require the global namespace versions of the functions to be provided. Using 66``std::`` is more consistent with the C++ Standard Library and makes it easier 67to distinguish Pigweed functions from library functions. 68 69Within core Pigweed, do not use C standard library functions that allocate 70memory, such as ``std::malloc``. There are exceptions to this for when dynamic 71allocation is enabled for a system; Pigweed modules are allowed to add extra 72functionality when a heap is present; but this must be optional. 73 74C++ Standard Library 75==================== 76Much of the C++ Standard Library is not a good fit for embedded software. Many 77of the classes and functions were not designed with the RAM, flash, and 78performance constraints of a microcontroller in mind. For example, simply 79adding the line ``#include <iostream>`` can increase the binary size by 150 KB! 80This is larger than many microcontrollers' entire internal storage. 81 82However, with appropriate caution, a limited set of standard C++ libraries can 83be used to great effect. Developers can leverage familiar, well-tested 84abstractions instead of writing their own. C++ library algorithms and classes 85can give equivalent or better performance than hand-written C code. 86 87A limited subset of the C++ Standard Library is permitted in Pigweed. To keep 88Pigweed small, flexible, and portable, functions that allocate dynamic memory 89must be avoided. Care must be exercised when using multiple instantiations of a 90template function, which can lead to code bloat. 91 92Permitted Headers 93----------------- 94.. admonition:: The following C++ Standard Library headers are always permitted: 95 :class: checkmark 96 97 * ``<array>`` 98 * ``<complex>`` 99 * ``<initializer_list>`` 100 * ``<iterator>`` 101 * ``<limits>`` 102 * ``<optional>`` 103 * ``<random>`` 104 * ``<ratio>`` 105 * ``<string_view>`` 106 * ``<tuple>`` 107 * ``<type_traits>`` 108 * ``<utility>`` 109 * ``<variant>`` 110 * C Standard Library headers (``<c*>``) 111 112.. admonition:: With caution, parts of the following headers can be used: 113 :class: warning 114 115 * ``<algorithm>`` -- be wary of potential memory allocation 116 * ``<atomic>`` -- not all MCUs natively support atomic operations 117 * ``<bitset>`` -- conversions to or from strings are disallowed 118 * ``<functional>`` -- do **not** use ``std::function``; use 119 :ref:`module-pw_function` 120 * ``<mutex>`` -- can use ``std::lock_guard``, use :ref:`module-pw_sync` for 121 mutexes 122 * ``<new>`` -- for placement new 123 * ``<numeric>`` -- be wary of code size with multiple template instantiations 124 125.. admonition:: Never use any of these headers: 126 :class: error 127 128 * Dynamic containers (``<list>``, ``<map>``, ``<set>``, ``<vector>``, etc.) 129 * Streams (``<iostream>``, ``<ostream>``, ``<fstream>``, ``<sstream>`` etc.) 130 -- in some cases :ref:`module-pw_stream` can work instead 131 * ``<span>`` -- use :ref:`module-pw_span` instead. Downstream projects may 132 want to directly use ``std::span`` if it is available, but upstream must 133 use the ``pw::span`` version for compatability 134 * ``<string>`` -- can use :ref:`module-pw_string` 135 * ``<thread>`` -- can use :ref:`module-pw_thread` 136 * ``<future>`` -- eventually :ref:`module-pw_async` will offer this 137 * ``<exception>``, ``<stdexcept>`` -- no exceptions 138 * ``<memory>``, ``<scoped_allocator>`` -- no allocations 139 * ``<regex>`` 140 * ``<valarray>`` 141 142Headers not listed here should be carefully evaluated before they are used. 143 144These restrictions do not apply to third party code or to projects that use 145Pigweed. 146 147Combining C and C++ 148=================== 149Prefer to write C++ code over C code, using ``extern "C"`` for symbols that must 150have C linkage. ``extern "C"`` functions should be defined within C++ 151namespaces to simplify referring to other code. 152 153C++ functions with no parameters do not include ``void`` in the parameter list. 154C functions with no parameters must include ``void``. 155 156.. code-block:: cpp 157 158 namespace pw { 159 160 bool ThisIsACppFunction() { return true; } 161 162 extern "C" int pw_ThisIsACFunction(void) { return -1; } 163 164 extern "C" { 165 166 int pw_ThisIsAlsoACFunction(void) { 167 return ThisIsACppFunction() ? 100 : 0; 168 } 169 170 } // extern "C" 171 172 } // namespace pw 173 174Comments 175======== 176Prefer C++-style (``//``) comments over C-style comments (``/* */``). C-style 177comments should only be used for inline comments. 178 179.. code-block:: cpp 180 181 // Use C++-style comments, except where C-style comments are necessary. 182 // This returns a random number using an algorithm I found on the internet. 183 #define RANDOM_NUMBER() [] { \ 184 return 4; /* chosen by fair dice roll */ \ 185 }() 186 187Indent code in comments with two additional spaces, making a total of three 188spaces after the ``//``. All code blocks must begin and end with an empty 189comment line, even if the blank comment line is the last line in the block. 190 191.. code-block:: cpp 192 193 // Here is an example of code in comments. 194 // 195 // int indentation_spaces = 2; 196 // int total_spaces = 3; 197 // 198 // engine_1.thrust = RANDOM_NUMBER() * indentation_spaces + total_spaces; 199 // 200 bool SomeFunction(); 201 202Passing move-only or expensive-to-copy arguments 203================================================ 204C++ offers a number of ways to pass arguments arguments to functions. 205When taking move-only or expensive-to-copy arguments, use the following table 206to determine which argument type to use: 207 208.. list-table:: C++ argument type choices 209 :widths: 30 20 10 210 :header-rows: 1 211 212 * - Use-case 213 - Name 214 - Syntax 215 * - If read-only 216 - By const reference 217 - ``const T&`` 218 * - If mutating 219 - By reference 220 - ``T&`` 221 * - If consuming 222 - By rvalue reference 223 - ``T&&`` 224 * - If conditionally consuming 225 - By value 226 - ``T`` 227 228Why rvalue references 229--------------------- 230When a function consumes or moves such an argument, it should accept an rvalue 231reference (``T&&``) rather than taking the argument by-value (``T``). An rvalue 232reference forces the caller to ``std::move`` when passing a preexisting 233variable, which makes the transfer of ownership explicit. 234 235Compared with accepting arguments by-value, rvalue references prevent 236unnecessary object instances and extra calls to move constructors. This has been 237shown to significantly impact code size and stack usage for Pigweed users. 238 239This is especially important when using ``pw::Function``. For more information 240about accepting ``pw::Function`` arguments, see 241:ref:`module-pw_function-move-semantics`. 242 243.. admonition:: **Yes**: Accept move-only or expensive-to-copy values by rvalue: 244 :class: checkmark 245 246 .. code-block:: cpp 247 248 void FrobulateVector(pw::Vector<T>&& vector) { 249 Frobulate(std::move(vector)); 250 } 251 252.. admonition:: **No**: Accepts move-only or expensive-to-copy values by value: 253 :class: error 254 255 .. code-block:: cpp 256 257 void FrobulateVector(pw::Vector<T> vector) { 258 Frobulate(std::move(vector)); 259 } 260 261This guidance overrides the standard `Google style guidance on rvalues 262<https://google.github.io/styleguide/cppguide.html#Rvalue_references>`_. 263 264Conditionally moving values 265--------------------------- 266An exception to the rule above is when a move-only or expensive-to-copy value 267is only conditionally consumed by the body of the function, for example: 268 269.. admonition:: **No**: Conditionally consumes ``vector``: 270 :class: error 271 272 .. code-block:: cpp 273 274 void PossiblyFrobulate(bool should_frob, pw::Vector<T>&& vector) { 275 if (should_frob) { 276 Frobulate(std::move(vector)); 277 } 278 } 279 280Because ``PossiblyFrobulate`` above will only consume ``vector`` in some code 281paths, the original ``vector`` passed by the user will outlive the call to 282``PossiblyFrobulate``: 283 284.. code-block:: cpp 285 286 pw::Vector<T> my_vec = ...; 287 288 // ``my_vec`` looks to be moved here, but the resulting ``rvalue`` is never 289 // consumed by ``PossiblyFrobulate``. 290 PossiblyFrobulate(false, std::move(my_vec)); 291 292 ... // some other long-running work 293 294 // ``my_vec`` is still alive here, possibly causing excess memory usage, 295 // deadlocks, or even undefined behavior! 296 297When conditionally consuming an argument, prefer instead to either accept 298the argument by-value or ensure that it is consumed by all control paths: 299 300.. admonition:: **Yes**: Conditionally consumes by-value ``vector``: 301 :class: checkmark 302 303 .. code-block:: cpp 304 305 void PossiblyFrobulate(bool should_frob, pw::Vector<T> vector) { 306 if (should_frob) { 307 Frobulate(std::move(vector)); 308 } 309 } 310 311.. admonition:: **Yes**: Consumes ``vector`` on all control paths: 312 :class: checkmark 313 314 .. code-block:: cpp 315 316 void PossiblyFrobulate(bool should_frob, pw::Vector<T>&& vector) { 317 if (should_frob) { 318 Frobulate(std::move(vector)); 319 } else { 320 [[maybe_unused]] auto to_discard = std::move(vector); 321 } 322 } 323 324Control statements 325================== 326 327Loops and conditionals 328---------------------- 329All loops and conditional statements must use braces, and be on their own line. 330 331.. admonition:: **Yes**: Always use braces for line conditionals and loops: 332 :class: checkmark 333 334 .. code-block:: cpp 335 336 while (SomeCondition()) { 337 x += 2; 338 } 339 if (OtherCondition()) { 340 DoTheThing(); 341 } 342 343 344.. admonition:: **No**: Missing braces 345 :class: error 346 347 .. code-block:: cpp 348 349 while (SomeCondition()) 350 x += 2; 351 if (OtherCondition()) 352 DoTheThing(); 353 354.. admonition:: **No**: Statement on same line as condition 355 :class: error 356 357 .. code-block:: cpp 358 359 while (SomeCondition()) { x += 2; } 360 if (OtherCondition()) { DoTheThing(); } 361 362 363The syntax ``while (true)`` is preferred over ``for (;;)`` for infinite loops. 364 365.. admonition:: **Yes**: 366 :class: checkmark 367 368 .. code-block:: cpp 369 370 while (true) { 371 DoSomethingForever(); 372 } 373 374.. admonition:: **No**: 375 :class: error 376 377 .. code-block:: cpp 378 379 for (;;) { 380 DoSomethingForever(); 381 } 382 383Do not declare empty infinite loops, which are undefined behavior. Instead, call 384:cpp:func:`pw::InfiniteLoop`. 385 386.. admonition:: **Yes**: 387 :class: checkmark 388 389 .. code-block:: cpp 390 391 pw::InfiniteLoop(); 392 393.. admonition:: **No**: 394 :class: error 395 396 .. code-block:: cpp 397 398 while (true) { 399 // The compiler may optimize out this loop! 400 } 401 402Prefer early exit with ``return`` and ``continue`` 403-------------------------------------------------- 404Prefer to exit early from functions and loops to simplify code. This is the 405same same conventions as `LLVM 406<https://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code>`_. 407We find this approach is superior to the "one return per function" style for a 408multitude of reasons: 409 410* **Visually**, the code is easier to follow, and takes less horizontal screen 411 space. 412* It makes it clear what part of the code is the **"main business" versus "edge 413 case handling"**. 414* For **functions**, parameter checking is in its own section at the top of the 415 function, rather than scattered around in the fuction body. 416* For **loops**, element checking is in its own section at the top of the loop, 417 rather than scattered around in the loop body. 418* Commit **deltas are simpler to follow** in code reviews; since adding a new 419 parameter check or loop element condition doesn't cause an indentation change 420 in the rest of the function. 421 422The guidance applies in two cases: 423 424* **Function early exit** - Early exits are for function parameter checking 425 and edge case checking at the top. The main functionality follows. 426* **Loop early exit** - Early exits in loops are for skipping an iteration 427 due to some edge case with an item getting iterated over. Loops may also 428 contain function exits, which should be structured the same way (see example 429 below). 430 431.. admonition:: **Yes**: Exit early from functions; keeping the main handling 432 at the bottom and de-dentend. 433 :class: checkmark 434 435 .. code-block:: cpp 436 437 Status DoSomething(Parameter parameter) { 438 // Parameter validation first; detecting incoming use errors. 439 PW_CHECK_INT_EQ(parameter.property(), 3, "Programmer error: frobnitz"); 440 441 // Error case: Not in correct state. 442 if (parameter.other() == MyEnum::kBrokenState) { 443 LOG_ERROR("Device in strange state: %s", parametr.state_str()); 444 return Status::InvalidPrecondition(); 445 } 446 447 // Error case: Not in low power mode; shouldn't do anything. 448 if (parameter.power() != MyEnum::kLowPower) { 449 LOG_ERROR("Not in low power mode"); 450 return Status::InvalidPrecondition(); 451 } 452 453 // Main business for the function here. 454 MainBody(); 455 MoreMainBodyStuff(); 456 } 457 458.. admonition:: **No**: Main body of function is buried and right creeping. 459 Even though this is shorter than the version preferred by Pigweed due to 460 factoring the return statement, the logical structure is less obvious. A 461 function in Pigweed containing **nested conditionals indicates that 462 something complicated is happening with the flow**; otherwise it would have 463 the early bail structure; so pay close attention. 464 :class: error 465 466 .. code-block:: cpp 467 468 Status DoSomething(Parameter parameter) { 469 // Parameter validation first; detecting incoming use errors. 470 PW_CHECK_INT_EQ(parameter.property(), 3, "Programmer error: frobnitz"); 471 472 // Error case: Not in correct state. 473 if (parameter.other() != MyEnum::kBrokenState) { 474 // Error case: Not in low power mode; shouldn't do anything. 475 if (parameter.power() == MyEnum::kLowPower) { 476 // Main business for the function here. 477 MainBody(); 478 MoreMainBodyStuff(); 479 } else { 480 LOG_ERROR("Not in low power mode"); 481 } 482 } else { 483 LOG_ERROR("Device in strange state: %s", parametr.state_str()); 484 } 485 return Status::InvalidPrecondition(); 486 } 487 488.. admonition:: **Yes**: Bail early from loops; keeping the main handling at 489 the bottom and de-dentend. 490 :class: checkmark 491 492 .. code-block:: cpp 493 494 for (int i = 0; i < LoopSize(); ++i) { 495 // Early skip of item based on edge condition. 496 if (!CommonCase()) { 497 continue; 498 } 499 // Early exit of function based on error case. 500 int my_measurement = GetSomeMeasurement(); 501 if (my_measurement < 10) { 502 LOG_ERROR("Found something strange; bailing"); 503 return Status::Unknown(); 504 } 505 506 // Main body of the loop. 507 ProcessItem(my_items[i], my_measurement); 508 ProcessItemMore(my_items[i], my_measurement, other_details); 509 ... 510 } 511 512.. admonition:: **No**: Right-creeping code with the main body buried inside 513 some nested conditional. This makes it harder to understand what is the 514 main purpose of the loop versus what is edge case handling. 515 :class: error 516 517 .. code-block:: cpp 518 519 for (int i = 0; i < LoopSize(); ++i) { 520 if (CommonCase()) { 521 int my_measurement = GetSomeMeasurement(); 522 if (my_measurement >= 10) { 523 // Main body of the loop. 524 ProcessItem(my_items[i], my_measurement); 525 ProcessItemMore(my_items[i], my_measurement, other_details); 526 ... 527 } else { 528 LOG_ERROR("Found something strange; bailing"); 529 return Status::Unknown(); 530 } 531 } 532 } 533 534There are cases where this structure doesn't work, and in those cases, it is 535fine to structure the code differently. 536 537No ``else`` after ``return`` or ``continue`` 538-------------------------------------------- 539Do not put unnecessary ``} else {`` blocks after blocks that terminate with a 540return, since this causes unnecessary rightward indentation creep. This 541guidance pairs with the preference for early exits to reduce code duplication 542and standardize loop/function structure. 543 544.. admonition:: **Yes**: No else after return or continue 545 :class: checkmark 546 547 .. code-block:: cpp 548 549 // Note lack of else block due to return. 550 if (Failure()) { 551 DoTheThing(); 552 return Status::ResourceExausted(); 553 } 554 555 // Note lack of else block due to continue. 556 while (MyCondition()) { 557 if (SomeEarlyBail()) { 558 continue; 559 } 560 // Main handling of item 561 ... 562 } 563 564 DoOtherThing(); 565 return OkStatus(); 566 567.. admonition:: **No**: Else after return needlessly creeps right 568 :class: error 569 570 .. code-block:: cpp 571 572 if (Failure()) { 573 DoTheThing(); 574 return Status::ResourceExausted(); 575 } else { 576 while (MyCondition()) { 577 if (SomeEarlyBail()) { 578 continue; 579 } else { 580 // Main handling of item 581 ... 582 } 583 } 584 DoOtherThing(); 585 return OkStatus(); 586 } 587 588Error handling 589============== 590Historically, exceptions have been avoided in embedded C++ as well as in general 591C++ code written at Google. Instead, assertions and error codes are used to 592communicate errors with less overhead. 593 594Signal and propagate non-fatal errors with ``pw::Status`` and ``pw::Result``, 595and assert/check for fatal errors. 596 597Add log statements to help with error tracking. See 598:ref:`guidance below <docs-pw-style-cpp-logging>` on how to craft high-value, 599low-noise logs. 600 601.. note: 602 603Like Google's C++ style guide, Pigweed does not use exceptions. The case for 604avoiding exceptions on embedded is primarily due to reducing code size. 605 606Recoverable errors 607------------------ 608Use the following to report non-fatal failures from subroutines: 609 610- :cpp:type:`pw::Status`: Zero-overhead type that wraps a 611 :ref:`status code <module-pw_status-quickref>`. 612- :ref:`pw::Result <module-pw_result>`: Union of a status code and a value. 613- :ref:`pw::StatusWithSize <module-pw_status-guide-status-with-size>`: A status 614 combined with a size. Especially useful for operations which may partially 615 succeed, such as a write that sent some bytes before failing. 616 617Fatal errors 618------------ 619Use :c:macro:`PW_ASSERT` and the :c:macro:`PW_CHECK` family of macros to halt 620execution on a fatal error. 621 622- These are appropriate when the security of the device is compromised. 623 624 - Example: memory corruption is detected. 625 626.. admonition:: **Yes** 627 :class: checkmark 628 629 .. code-block:: cpp 630 631 PW_CHECK_NOTNULL(item->next); 632 PW_CHECK_PTR_EQ(item, item->next->prev); 633 634- These may be appropriate for instances of unambiguous programmer error. 635 636 - Example: a caller passed a null pointer to a routine that explicitly 637 requires non-null pointers. 638 639.. warning:: 640 641 Be very careful about introducing new assertions into existing code, or in 642 code paths that are not exhaustively tested, or any other scenario that may 643 result in crashes in fielded devices. 644 645.. admonition:: **No**: May cause a runtime crash. 646 :class: error 647 648 .. code-block:: cpp 649 650 StatusWithSize sws = kvs.Get("some-key", &out); 651 PW_CHECK_OK(sws.status()); 652 653 The key may be missing from the :ref:`KVS <module-pw_kvs>` for a number of 654 reasons. It is likely better to surface this error to a higher level that can 655 decide how to handle a missing value. 656 657Include guards 658============== 659The first non-comment line of every header file must be ``#pragma once``. Do 660not use traditional macro include guards. The ``#pragma once`` should come 661directly after the Pigweed copyright block, with no blank line, followed by a 662blank, like this: 663 664.. code-block:: cpp 665 666 // Copyright 2021 The Pigweed Authors 667 // 668 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 669 // use this file except in compliance with the License. You may obtain a copy of 670 // the License at 671 // 672 // https://www.apache.org/licenses/LICENSE-2.0 673 // 674 // Unless required by applicable law or agreed to in writing, software 675 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 676 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 677 // License for the specific language governing permissions and limitations under 678 // the License. 679 #pragma once 680 681 // Header file-level comment goes here... 682 683.. _docs-pw-style-cpp-logging: 684 685Logging 686======= 687Good logging can be incredibly useful in detecting and debugging errors. Log 688quality is determined by the amount of useful information relative to overall 689amount of logs. 690 691Log in the right spot 692--------------------- 693Limiting logs to only the most relevant sections of code can guide developers to 694areas that require debugging. 695 696- **Log errors as soon as they can be umabiguously determined to be errors.** An 697 unambiguous error is one that will be reported to the caller of the module or 698 component. Avoid logging errors that are handled internally by the module or 699 component. 700 701 - Example: A task manager would not log a failure to schedule a specific 702 worker from a pool, but may log the failure to find *any* worker in the 703 pool. 704 705 .. admonition:: **No**: May log errors even if the call eventually succeeds. 706 :class: error 707 708 .. code-block:: cpp 709 710 Status TaskManager::AssignToWorker(Task& task) { 711 for (auto& worker : pool_) { 712 if (worker.AssignTask(task).ok()) { 713 return OkStatus(); 714 } 715 } 716 return Status::ResourceExhausted(); 717 } 718 719 Status Worker::Assign(Task& task) { 720 if (busy_) { 721 PW_LOG_DEBUG("failed to assign task to worker %zu", id_); 722 return Status::FailedPrecondition(); 723 } 724 // ... 725 } 726 727 .. admonition:: **Yes**: Only logs when an actual failure has occurred. 728 :class: checkmark 729 730 .. code-block:: cpp 731 732 Status TaskManager::AssignToWorker(Task& task) { 733 for (auto& worker : pool_) { 734 if (worker.AssignTask(task).ok()) { 735 return OkStatus(); 736 } 737 } 738 PW_LOG_DEBUG("failed to find a worker to handle the task"); 739 return Status::ResourceExhausted(); 740 } 741 742 Status Worker::Assign(Task& task) { 743 if (busy_) { 744 return Status::FailedPrecondition(); 745 } 746 // ... 747 } 748 749 750- **Log failures of an overall workflow at the level that it was initiated** to 751 provide context in which an error occurred. 752 753 - Example: A widget may log that it could not perform a user-scheduled task 754 because the task manager returned an error. 755 756- **Limit the use of informational logs of non-failure conditions.** These 757 "heartbeat" logs can quickly accrue and become noise. If needed, keep the 758 frequency of these logs low, e.g. not more than once per second. 759 :c:macro:`PW_LOG_EVERY_N` and :c:macro:`PW_LOG_EVERY_N_DURATION` can be used 760 to rate-limit such logs. 761 762 .. admonition:: **No**: May spew a large number of logs. 763 :class: error 764 765 .. code-block:: cpp 766 767 void OnChunk(const Chunk& chunk) { 768 ++count_; 769 total_ += chunk.size(); 770 PW_LOG_DEBUG("Processed %zu chunks totaling %zu bytes", count_, total_); 771 // ... 772 } 773 774 .. admonition:: **Yes**: Only logs once every 10 seconds. 775 :class: checkmark 776 777 .. code-block:: cpp 778 779 void OnChunk(const Packet& packet) { 780 static constexpr auto kLogInterval = 781 chrono::SystemClock::for_at_least(std::chrono::seconds(10)); 782 ++count_; 783 total_ += packet.size(); 784 PW_LOG_EVERY_N_DURATION(PW_LOG_LEVEL_DEBUG, 785 kLogInterval, 786 "Processed %zu chunks totaling %zu bytes", 787 count_, 788 total_); 789 } 790 791Log at the correct level 792------------------------ 793:ref:`Log levels <module-pw_log-levels>` indicate the seriousness of a message 794and provide a simple mechanism for conditional logging and for log filtering. 795 796- **Downstream projects should use less filtered log levels**, as 797 project-specific errors more likely indicate an actionable failure. 798 799 - Use :c:macro:`PW_LOG_CRITICAL` for failures that compromise the entire 800 device and will imminently halt or crash the device. 801 - Use :c:macro:`PW_LOG_ERROR` for failures that are more serious or harder to 802 recover from. 803 - Use :c:macro:`PW_LOG_WARN` for failures that are less serious or easier to 804 recover from. 805 - Use :c:macro:`PW_LOG_INFO` for informational logs of non-failure conditions. 806 807- **Libraries and upstream code should allow configurable logging.** Downstream 808 projects may want to disable library and module logging to save on code size, 809 or enable it to aid in debugging. 810 811 - Use :c:macro:`PW_LOG_DEBUG` to log specific errors that the caller is 812 expected to handle. 813 814 .. admonition:: **Yes** 815 :class: checkmark 816 817 .. code-block:: cpp 818 819 if (stream.IsClosed()) { 820 PW_LOG_DEBUG("Stream closed unexpectedly"); 821 return Status::OutOfRange(); 822 } 823 824 - Use :c:macro:`PW_LOG_INFO` and :c:macro:`PW_LOG_WARN` to communicate error 825 conditions that may not have a caller that can handle them. 826 827 .. admonition:: **Yes** 828 :class: checkmark 829 830 .. code-block:: cpp 831 832 while(!task_queue_.empty()) { 833 Task task = std::move(task_queue_.back()); 834 task_queue_.pop_back(); 835 if (task.HasExpired()) { 836 PW_LOG_INFO("Task %zu expired before being scheduled", task.id()); 837 continue; 838 } 839 Schedule(std::move(task)); 840 // ... 841 } 842 843 - Set a :c:macro:`PW_LOG_LEVEL`. If logging in a module with a 844 :ref:`module configuration <module-structure-compile-time-configuration>`, 845 include a logging option and set :c:macro:`PW_LOG_LEVEL` to it. 846 847 .. admonition:: **Yes** 848 :class: checkmark 849 850 .. code-block:: cpp 851 852 // In my_module's config.h. Can be overridden at compile time. 853 #ifndef MY_MODULE_LOG_LEVEL 854 #define MY_MODULE_LOG_LEVEL PW_LOG_LEVEL_WARN 855 #endif MY_MODULE_LOG_LEVEL 856 857 // In my_module's source files. 858 #include "my_module/config.h" 859 #define PW_LOG_LEVEL MY_MODULE_LOG_LEVEL 860 861Log the right information 862------------------------- 863Logging the most useful information requires considering what may be relevant to 864an error and cannot be obtained another way. 865 866- **Include relevant context**, such as function parameters. 867- **Capitalize your log message, but do not end with puncuation.** Log backends 868 typically combine your log message with additional information and format 869 them. 870 871.. admonition:: **No** 872 :class: error 873 874 .. code-block:: cpp 875 876 PW_LOG_DEBUG("the operation did not complete normally."); 877 878.. admonition:: **Yes** 879 :class: checkmark 880 881 .. code-block:: cpp 882 883 PW_LOG_DEBUG("The operation completed normally"); 884 885- **Set** :c:macro:`PW_LOG_MODULE_NAME` to include a 886 module name that you can filter on. 887 888.. admonition:: **Yes** 889 :class: checkmark 890 891 .. code-block:: cpp 892 893 #define PW_LOG_MODULE_NAME "my_module" 894 895- **Do not include source location details.** The log backend can be configured 896 to add various :ref:`module-pw_log-logging_attributes` automatically. 897 898.. admonition:: **No** 899 :class: error 900 901 .. code-block:: cpp 902 903 PW_LOG_DEBUG("%s:%d: %s called", __FILE__, __LINE__, __PRETTY_FUNCTION__); 904 905- **Do not log** :cpp:type:`pw::Status` **details.** If you are logging and 906 returning an error as a result of a subroutine that returned an error, it is 907 likely that a log statement can be added closer to where that error was 908 detected. 909 910.. admonition:: **No** 911 :class: error 912 913 .. code-block:: cpp 914 915 Result<Message> ReadAndDecode(Stream& stream) { 916 Result<EncodedMessage> result = ReadEncodedMessage(stream); 917 if (!result.ok()) { 918 Status status = result.status(); 919 PW_LOG_DEBUG("Failed to read message: %s", 920 pw_StatusString(status.code)); 921 return status; 922 } 923 // ... 924 } 925 926Memory allocation 927================= 928Dynamic memory allocation can be problematic. Heap allocations and deallocations 929occupy valuable CPU cycles. Memory usage becomes nondeterministic, which can 930result in a system crashing without a clear culprit. 931 932To keep Pigweed portable, core Pigweed code is not permitted to dynamically 933(heap) allocate memory, such as with ``malloc`` or ``new``. All memory should be 934allocated with automatic (stack) or static (global) storage duration. Pigweed 935must not use C++ libraries that use dynamic allocation. 936 937Projects that use Pigweed are free to use dynamic allocation, provided they 938have selected a target that enables the heap. 939 940Naming 941====== 942Entities shall be named according to the `Google style guide 943<https://google.github.io/styleguide/cppguide.html>`_, with the following 944additional requirements. 945 946C++ code 947-------- 948* All Pigweed C++ code must be in the ``pw`` namespace. Namespaces for modules 949 should be nested under ``pw``. For example, ``pw::string::Format()``. 950* Whenever possible, private code should be in a source (.cc) file and placed in 951 anonymous namespace nested under ``pw``. Unit tests must be declared in an 952 anonymous namespace to avoid potential linking issues when building multiple 953 tests in one binary. 954* If private code must be exposed in a header file, it must be in a namespace 955 nested under ``pw``. The namespace may be named for its subsystem or use a 956 name that designates it as private, such as ``internal``. 957* Template arguments for non-type names (e.g. ``template <int kFooBar>``) should 958 follow the constexpr and const variable Google naming convention, which means 959 k prefixed camel case (e.g. ``kCamelCase``). This matches the Google C++ 960 style for variable naming, however the wording in the official style guide 961 isn't explicit for template arguments and could be interpreted to use 962 ``foo_bar`` style naming. For consistency with other variables whose value is 963 always fixed for the duration of the program, the naming convention is 964 ``kCamelCase``, and so that is the style we use in Pigweed. 965* Trivial membor accessors should be named with ``snake_case()``. The Google 966 C++ style allows either ``snake_case()`` or ``CapsCase()``, but Pigweed 967 always uses ``snake_case()``. 968* Abstract base classes should be named generically, with derived types named 969 specifically. For example, ``Stream`` is an abstract base, and 970 ``SocketStream`` and ``StdioStream`` are an implementations of that 971 interface. Any prefix or postfix indicating whether something is abstract or 972 concrete is not permitted; for example, ``IStream`` or ``SocketStreamImpl`` 973 are both not permitted. These pre-/post-fixes add additional visual noise and 974 are irrelevant to consumers of these interfaces. 975 976C code 977------ 978In general, C symbols should be prefixed with the module name. If the symbol is 979not associated with a module, use just ``pw`` as the module name. Facade 980backends may chose to prefix symbols with the facade's name to help reduce the 981length of the prefix. 982 983* Public names used by C code must be prefixed with the module name (e.g. 984 ``pw_tokenizer_*``). 985* If private code must be exposed in a header, private names used by C code must 986 be prefixed with an underscore followed by the module name (e.g. 987 ``_pw_assert_*``). 988* Avoid writing C source (.c) files in Pigweed. Prefer to write C++ code with C 989 linkage using ``extern "C"``. Within C source, private C functions and 990 variables must be named with the ``_pw_my_module_*`` prefix and should be 991 declared ``static`` whenever possible; for example, 992 ``_pw_my_module_MyPrivateFunction``. 993* The C prefix rules apply to 994 995 * C functions (``int pw_foo_FunctionName(void);``), 996 * variables used by C code (``int pw_foo_variable_name;``), 997 * constant variables used by C code (``const int pw_foo_kConstantName;``), 998 * structs used by C code (``typedef struct {} pw_foo_StructName;``), and 999 * all of the above for ``extern "C"`` names in C++ code. 1000 1001 The prefix does not apply to struct members, which use normal Google style. 1002 1003Preprocessor macros 1004------------------- 1005* Public Pigweed macros must be prefixed with the module name (e.g. 1006 ``PW_MY_MODULE_*``). 1007* Private Pigweed macros must be prefixed with an underscore followed by the 1008 module name (e.g. ``_PW_MY_MODULE_*``). (This style may change, see 1009 `b/234886184 <https://issuetracker.google.com/issues/234886184>`_). 1010 1011**Example** 1012 1013.. code-block:: cpp 1014 1015 namespace pw::my_module { 1016 namespace nested_namespace { 1017 1018 // C++ names (types, variables, functions) must be in the pw namespace. 1019 // They are named according to the Google style guide. 1020 constexpr int kGlobalConstant = 123; 1021 1022 // Prefer using functions over extern global variables. 1023 extern int global_variable; 1024 1025 class Class {}; 1026 1027 void Function(); 1028 1029 extern "C" { 1030 1031 // Public Pigweed code used from C must be prefixed with pw_. 1032 extern const int pw_my_module_kGlobalConstant; 1033 1034 extern int pw_my_module_global_variable; 1035 1036 void pw_my_module_Function(void); 1037 1038 typedef struct { 1039 int member_variable; 1040 } pw_my_module_Struct; 1041 1042 // Private Pigweed code used from C must be prefixed with _pw_. 1043 extern const int _pw_my_module_kPrivateGlobalConstant; 1044 1045 extern int _pw_my_module_private_global_variable; 1046 1047 void _pw_my_module_PrivateFunction(void); 1048 1049 typedef struct { 1050 int member_variable; 1051 } _pw_my_module_PrivateStruct; 1052 1053 } // extern "C" 1054 1055 // Public macros must be prefixed with PW_. 1056 #define PW_MY_MODULE_PUBLIC_MACRO(arg) arg 1057 1058 // Private macros must be prefixed with _PW_. 1059 #define _PW_MY_MODULE_PRIVATE_MACRO(arg) arg 1060 1061 } // namespace nested_namespace 1062 } // namespace pw::my_module 1063 1064See :ref:`docs-pw-style-macros` for details about macro usage. 1065 1066Namespace scope formatting 1067========================== 1068All non-indented blocks (namespaces, ``extern "C"`` blocks, and preprocessor 1069conditionals) must have a comment on their closing line with the 1070contents of the starting line. 1071 1072All nested namespaces should be declared together with no blank lines between 1073them. 1074 1075.. code-block:: cpp 1076 1077 #include "some/header.h" 1078 1079 namespace pw::nested { 1080 namespace { 1081 1082 constexpr int kAnonConstantGoesHere = 0; 1083 1084 } // namespace 1085 1086 namespace other { 1087 1088 const char* SomeClass::yes = "no"; 1089 1090 bool ThisIsAFunction() { 1091 #if PW_CONFIG_IS_SET 1092 return true; 1093 #else 1094 return false; 1095 #endif // PW_CONFIG_IS_SET 1096 } 1097 1098 extern "C" { 1099 1100 const int pw_kSomeConstant = 10; 1101 int pw_some_global_variable = 600; 1102 1103 void pw_CFunction() { ... } 1104 1105 } // extern "C" 1106 1107 } // namespace 1108 } // namespace pw::nested 1109 1110Using directives for literals 1111============================= 1112`Using-directives 1113<https://en.cppreference.com/w/cpp/language/namespace#Using-directives>`_ (e.g. 1114``using namespace ...``) are permitted in implementation files only for the 1115purposes of importing literals such as ``std::chrono_literals`` or 1116``pw::bytes::unit_literals``. Namespaces that contain any symbols other than 1117literals are not permitted in a using-directive. This guidance also has no 1118impact on `using-declarations 1119<https://en.cppreference.com/w/cpp/language/namespace#Using-declarations>`_ 1120(e.g. ``using foo::Bar;``). 1121 1122Rationale: Literals improve code readability, making units clearer at the point 1123of definition. 1124 1125.. code-block:: cpp 1126 1127 using namespace std::chrono; // Not allowed 1128 using namespace std::literals::chrono_literals; // Allowed 1129 1130 constexpr std::chrono::duration delay = 250ms; 1131 1132Pointers and references 1133======================= 1134For pointer and reference types, place the asterisk or ampersand next to the 1135type. 1136 1137.. code-block:: cpp 1138 1139 int* const number = &that_thing; 1140 constexpr const char* kString = "theory!" 1141 1142 bool FindTheOneRing(const Region& where_to_look) { ... } 1143 1144Prefer storing references over storing pointers. Pointers are required when the 1145pointer can change its target or may be ``nullptr``. Otherwise, a reference or 1146const reference should be used. 1147 1148.. _docs-pw-style-macros: 1149 1150Preprocessor macros 1151=================== 1152Macros should only be used when they significantly improve upon the C++ code 1153they replace. Macros should make code more readable, robust, and safe, or 1154provide features not possible with standard C++, such as stringification, line 1155number capturing, or conditional compilation. When possible, use C++ constructs 1156like constexpr variables in place of macros. Never use macros as constants, 1157except when a string literal is needed or the value must be used by C code. 1158 1159When macros are needed, the macros should be accompanied with extensive tests 1160to ensure the macros are hard to use wrong. 1161 1162Stand-alone statement macros 1163---------------------------- 1164Macros that are standalone statements must require the caller to terminate the 1165macro invocation with a semicolon (see `Swalling the Semicolon 1166<https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html>`_). For 1167example, the following does *not* conform to Pigweed's macro style: 1168 1169.. code-block:: cpp 1170 1171 // BAD! Definition has built-in semicolon. 1172 #define PW_LOG_IF_BAD(mj) \ 1173 CallSomeFunction(mj); 1174 1175 // BAD! Compiles without error; semicolon is missing. 1176 PW_LOG_IF_BAD("foo") 1177 1178Here's how to do this instead: 1179 1180.. code-block:: cpp 1181 1182 // GOOD; requires semicolon to compile. 1183 #define PW_LOG_IF_BAD(mj) \ 1184 CallSomeFunction(mj) 1185 1186 // GOOD; fails to compile due to lacking semicolon. 1187 PW_LOG_IF_BAD("foo") 1188 1189For macros in function scope that do not already require a semicolon, the 1190contents can be placed in a ``do { ... } while (0)`` loop. 1191 1192.. code-block:: cpp 1193 1194 #define PW_LOG_IF_BAD(mj) \ 1195 do { \ 1196 if (mj.Bad()) { \ 1197 Log(#mj " is bad") \ 1198 } \ 1199 } while (0) 1200 1201Standalone macros at global scope that do not already require a semicolon can 1202add a ``static_assert`` declaration statement as their last line. 1203 1204.. code-block:: cpp 1205 1206 #define PW_NEAT_THING(thing) \ 1207 bool IsNeat_##thing() { return true; } \ 1208 static_assert(true, "Macros must be terminated with a semicolon") 1209 1210Private macros in public headers 1211-------------------------------- 1212Private macros in public headers must be prefixed with ``_PW_``, even if they 1213are undefined after use; this prevents collisions with downstream users. For 1214example: 1215 1216.. code-block:: cpp 1217 1218 #define _PW_MY_SPECIAL_MACRO(op) ... 1219 ... 1220 // Code that uses _PW_MY_SPECIAL_MACRO() 1221 ... 1222 #undef _PW_MY_SPECIAL_MACRO 1223 1224Macros in private implementation files (.cc) 1225-------------------------------------------- 1226Macros within .cc files that should only be used within one file should be 1227undefined after their last use; for example: 1228 1229.. code-block:: cpp 1230 1231 #define DEFINE_OPERATOR(op) \ 1232 T operator ## op(T x, T y) { return x op y; } \ 1233 static_assert(true, "Macros must be terminated with a semicolon") \ 1234 1235 DEFINE_OPERATOR(+); 1236 DEFINE_OPERATOR(-); 1237 DEFINE_OPERATOR(/); 1238 DEFINE_OPERATOR(*); 1239 1240 #undef DEFINE_OPERATOR 1241 1242Preprocessor conditional statements 1243=================================== 1244When using macros for conditional compilation, prefer to use ``#if`` over 1245``#ifdef``. This checks the value of the macro rather than whether it exists. 1246 1247* ``#if`` handles undefined macros equivalently to ``#ifdef``. Undefined 1248 macros expand to 0 in preprocessor conditional statements. 1249* ``#if`` evaluates false for macros defined as 0, while ``#ifdef`` evaluates 1250 true. 1251* Macros defined using compiler flags have a default value of 1 in GCC and 1252 Clang, so they work equivalently for ``#if`` and ``#ifdef``. 1253* Macros defined to an empty statement cause compile-time errors in ``#if`` 1254 statements, which avoids ambiguity about how the macro should be used. 1255 1256All ``#endif`` statements should be commented with the expression from their 1257corresponding ``#if``. Do not indent within preprocessor conditional statements. 1258 1259.. code-block:: cpp 1260 1261 #if USE_64_BIT_WORD 1262 using Word = uint64_t; 1263 #else 1264 using Word = uint32_t; 1265 #endif // USE_64_BIT_WORD 1266 1267Unsigned integers 1268================= 1269Unsigned integers are permitted in Pigweed. Aim for consistency with existing 1270code and the C++ Standard Library. Be very careful mixing signed and unsigned 1271integers. 1272 1273Features not in the C++ standard 1274================================ 1275Avoid features not available in standard C++. This includes compiler extensions 1276and features from other standards like POSIX. 1277 1278For example, use ``ptrdiff_t`` instead of POSIX's ``ssize_t``, unless 1279interacting with a POSIX API in intentionally non-portable code. Never use 1280POSIX functions with suitable standard or Pigweed alternatives, such as 1281``strnlen`` (use ``pw::string::NullTerminatedLength`` instead). 1282