xref: /aosp_15_r20/external/pigweed/docs/style/cpp.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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
383
384Prefer early exit with ``return`` and ``continue``
385--------------------------------------------------
386Prefer to exit early from functions and loops to simplify code. This is the
387same same conventions as `LLVM
388<https://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code>`_.
389We find this approach is superior to the "one return per function" style for a
390multitude of reasons:
391
392* **Visually**, the code is easier to follow, and takes less horizontal screen
393  space.
394* It makes it clear what part of the code is the **"main business" versus "edge
395  case handling"**.
396* For **functions**, parameter checking is in its own section at the top of the
397  function, rather than scattered around in the fuction body.
398* For **loops**, element checking is in its own section at the top of the loop,
399  rather than scattered around in the loop body.
400* Commit **deltas are simpler to follow** in code reviews; since adding a new
401  parameter check or loop element condition doesn't cause an indentation change
402  in the rest of the function.
403
404The guidance applies in two cases:
405
406* **Function early exit** - Early exits are for function parameter checking
407  and edge case checking at the top. The main functionality follows.
408* **Loop early exit** - Early exits in loops are for skipping an iteration
409  due to some edge case with an item getting iterated over. Loops may also
410  contain function exits, which should be structured the same way (see example
411  below).
412
413.. admonition:: **Yes**: Exit early from functions; keeping the main handling
414   at the bottom and de-dentend.
415   :class: checkmark
416
417   .. code-block:: cpp
418
419      Status DoSomething(Parameter parameter) {
420        // Parameter validation first; detecting incoming use errors.
421        PW_CHECK_INT_EQ(parameter.property(), 3, "Programmer error: frobnitz");
422
423        // Error case: Not in correct state.
424        if (parameter.other() == MyEnum::kBrokenState) {
425          LOG_ERROR("Device in strange state: %s", parametr.state_str());
426          return Status::InvalidPrecondition();
427        }
428
429        // Error case: Not in low power mode; shouldn't do anything.
430        if (parameter.power() != MyEnum::kLowPower) {
431          LOG_ERROR("Not in low power mode");
432          return Status::InvalidPrecondition();
433        }
434
435        // Main business for the function here.
436        MainBody();
437        MoreMainBodyStuff();
438      }
439
440.. admonition:: **No**: Main body of function is buried and right creeping.
441   Even though this is shorter than the version preferred by Pigweed due to
442   factoring the return statement, the logical structure is less obvious. A
443   function in Pigweed containing **nested conditionals indicates that
444   something complicated is happening with the flow**; otherwise it would have
445   the early bail structure; so pay close attention.
446   :class: error
447
448   .. code-block:: cpp
449
450      Status DoSomething(Parameter parameter) {
451        // Parameter validation first; detecting incoming use errors.
452        PW_CHECK_INT_EQ(parameter.property(), 3, "Programmer error: frobnitz");
453
454        // Error case: Not in correct state.
455        if (parameter.other() != MyEnum::kBrokenState) {
456          // Error case: Not in low power mode; shouldn't do anything.
457          if (parameter.power() == MyEnum::kLowPower) {
458            // Main business for the function here.
459            MainBody();
460            MoreMainBodyStuff();
461          } else {
462            LOG_ERROR("Not in low power mode");
463          }
464        } else {
465          LOG_ERROR("Device in strange state: %s", parametr.state_str());
466        }
467        return Status::InvalidPrecondition();
468      }
469
470.. admonition:: **Yes**: Bail early from loops; keeping the main handling at
471   the bottom and de-dentend.
472   :class: checkmark
473
474   .. code-block:: cpp
475
476      for (int i = 0; i < LoopSize(); ++i) {
477        // Early skip of item based on edge condition.
478        if (!CommonCase()) {
479          continue;
480        }
481        // Early exit of function based on error case.
482        int my_measurement = GetSomeMeasurement();
483        if (my_measurement < 10) {
484          LOG_ERROR("Found something strange; bailing");
485          return Status::Unknown();
486        }
487
488        // Main body of the loop.
489        ProcessItem(my_items[i], my_measurement);
490        ProcessItemMore(my_items[i], my_measurement, other_details);
491        ...
492      }
493
494.. admonition:: **No**: Right-creeping code with the main body buried inside
495   some nested conditional. This makes it harder to understand what is the
496   main purpose of the loop versus what is edge case handling.
497   :class: error
498
499   .. code-block:: cpp
500
501      for (int i = 0; i < LoopSize(); ++i) {
502        if (CommonCase()) {
503          int my_measurement = GetSomeMeasurement();
504          if (my_measurement >= 10) {
505            // Main body of the loop.
506            ProcessItem(my_items[i], my_measurement);
507            ProcessItemMore(my_items[i], my_measurement, other_details);
508            ...
509          } else {
510            LOG_ERROR("Found something strange; bailing");
511            return Status::Unknown();
512          }
513        }
514      }
515
516There are cases where this structure doesn't work, and in those cases, it is
517fine to structure the code differently.
518
519No ``else`` after ``return`` or ``continue``
520--------------------------------------------
521Do not put unnecessary ``} else {`` blocks after blocks that terminate with a
522return, since this causes unnecessary rightward indentation creep. This
523guidance pairs with the preference for early exits to reduce code duplication
524and standardize loop/function structure.
525
526.. admonition:: **Yes**: No else after return or continue
527   :class: checkmark
528
529   .. code-block:: cpp
530
531      // Note lack of else block due to return.
532      if (Failure()) {
533        DoTheThing();
534        return Status::ResourceExausted();
535      }
536
537      // Note lack of else block due to continue.
538      while (MyCondition()) {
539        if (SomeEarlyBail()) {
540          continue;
541        }
542        // Main handling of item
543        ...
544      }
545
546      DoOtherThing();
547      return OkStatus();
548
549.. admonition:: **No**: Else after return needlessly creeps right
550   :class: error
551
552   .. code-block:: cpp
553
554      if (Failure()) {
555        DoTheThing();
556        return Status::ResourceExausted();
557      } else {
558        while (MyCondition()) {
559          if (SomeEarlyBail()) {
560            continue;
561          } else {
562            // Main handling of item
563            ...
564          }
565        }
566        DoOtherThing();
567        return OkStatus();
568      }
569
570Error handling
571==============
572Historically, exceptions have been avoided in embedded C++ as well as in general
573C++ code written at Google. Instead, assertions and error codes are used to
574communicate errors with less overhead.
575
576Signal and propagate non-fatal errors with ``pw::Status`` and ``pw::Result``,
577and assert/check for fatal errors.
578
579Add log statements to help with error tracking. See
580:ref:`guidance below <docs-pw-style-cpp-logging>` on how to craft high-value,
581low-noise logs.
582
583.. note:
584
585Like Google's C++ style guide, Pigweed does not use exceptions. The case for
586avoiding exceptions on embedded is primarily due to reducing code size.
587
588Recoverable errors
589------------------
590Use the following to report non-fatal failures from subroutines:
591
592- :cpp:type:`pw::Status`: Zero-overhead type that wraps a
593  :ref:`status code <module-pw_status-quickref>`.
594- :ref:`pw::Result <module-pw_result>`: Union of a status code and a value.
595- :ref:`pw::StatusWithSize <module-pw_status-guide-status-with-size>`: A status
596  combined with a size. Especially useful for operations which may partially
597  succeed, such as a write that sent some bytes before failing.
598
599Fatal errors
600------------
601Use :c:macro:`PW_ASSERT` and the :c:macro:`PW_CHECK` family of macros to halt
602execution on a fatal error.
603
604- These are appropriate when the security of the device is compromised.
605
606  - Example: memory corruption is detected.
607
608.. admonition:: **Yes**
609   :class: checkmark
610
611   .. code-block:: cpp
612
613      PW_CHECK_NOTNULL(item->next);
614      PW_CHECK_PTR_EQ(item, item->next->prev);
615
616- These may be appropriate for instances of unambiguous programmer error.
617
618  - Example: a caller passed a null pointer to a routine that explicitly
619    requires non-null pointers.
620
621.. warning::
622
623   Be very careful about introducing new assertions into existing code, or in
624   code paths that are not exhaustively tested, or any other scenario that may
625   result in crashes in fielded devices.
626
627.. admonition:: **No**: May cause a runtime crash.
628   :class: error
629
630   .. code-block:: cpp
631
632      StatusWithSize sws = kvs.Get("some-key", &out);
633      PW_CHECK_OK(sws.status());
634
635   The key may be missing from the :ref:`KVS <module-pw_kvs>` for a number of
636   reasons. It is likely better to surface this error to a higher level that can
637   decide how to handle a missing value.
638
639Include guards
640==============
641The first non-comment line of every header file must be ``#pragma once``. Do
642not use traditional macro include guards. The ``#pragma once`` should come
643directly after the Pigweed copyright block, with no blank line, followed by a
644blank, like this:
645
646.. code-block:: cpp
647
648   // Copyright 2021 The Pigweed Authors
649   //
650   // Licensed under the Apache License, Version 2.0 (the "License"); you may not
651   // use this file except in compliance with the License. You may obtain a copy of
652   // the License at
653   //
654   //     https://www.apache.org/licenses/LICENSE-2.0
655   //
656   // Unless required by applicable law or agreed to in writing, software
657   // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
658   // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
659   // License for the specific language governing permissions and limitations under
660   // the License.
661   #pragma once
662
663   // Header file-level comment goes here...
664
665.. _docs-pw-style-cpp-logging:
666
667Logging
668=======
669Good logging can be incredibly useful in detecting and debugging errors. Log
670quality is determined by the amount of useful information relative to overall
671amount of logs.
672
673Log in the right spot
674---------------------
675Limiting logs to only the most relevant sections of code can guide developers to
676areas that require debugging.
677
678- **Log errors as soon as they can be umabiguously determined to be errors.** An
679  unambiguous error is one that will be reported to the caller of the module or
680  component. Avoid logging errors that are handled internally by the module or
681  component.
682
683  - Example: A task manager would not log a failure to schedule a specific
684    worker from a pool, but may log the failure to find *any* worker in the
685    pool.
686
687    .. admonition:: **No**: May log errors even if the call eventually succeeds.
688       :class: error
689
690       .. code-block:: cpp
691
692          Status TaskManager::AssignToWorker(Task& task) {
693            for (auto& worker : pool_) {
694              if (worker.AssignTask(task).ok()) {
695                return OkStatus();
696              }
697            }
698            return Status::ResourceExhausted();
699          }
700
701          Status Worker::Assign(Task& task) {
702            if (busy_) {
703              PW_LOG_DEBUG("failed to assign task to worker %zu", id_);
704              return Status::FailedPrecondition();
705            }
706            // ...
707          }
708
709    .. admonition:: **Yes**: Only logs when an actual failure has occurred.
710       :class: checkmark
711
712       .. code-block:: cpp
713
714          Status TaskManager::AssignToWorker(Task& task) {
715            for (auto& worker : pool_) {
716              if (worker.AssignTask(task).ok()) {
717                return OkStatus();
718              }
719            }
720            PW_LOG_DEBUG("failed to find a worker to handle the task");
721            return Status::ResourceExhausted();
722          }
723
724          Status Worker::Assign(Task& task) {
725            if (busy_) {
726              return Status::FailedPrecondition();
727            }
728            // ...
729          }
730
731
732- **Log failures of an overall workflow at the level that it was initiated** to
733  provide context in which an error occurred.
734
735  - Example: A widget may log that it could not perform a user-scheduled task
736    because the task manager returned an error.
737
738- **Limit the use of informational logs of non-failure conditions.** These
739  "heartbeat" logs can quickly accrue and become noise. If needed, keep the
740  frequency of these logs low, e.g. not more than once per second.
741  :c:macro:`PW_LOG_EVERY_N` and :c:macro:`PW_LOG_EVERY_N_DURATION` can be used
742  to rate-limit such logs.
743
744  .. admonition:: **No**: May spew a large number of logs.
745     :class: error
746
747     .. code-block:: cpp
748
749        void OnChunk(const Chunk& chunk) {
750          ++count_;
751          total_ += chunk.size();
752          PW_LOG_DEBUG("Processed %zu chunks totaling %zu bytes", count_, total_);
753          // ...
754        }
755
756  .. admonition:: **Yes**: Only logs once every 10 seconds.
757     :class: checkmark
758
759     .. code-block:: cpp
760
761        void OnChunk(const Packet& packet) {
762          static constexpr auto kLogInterval =
763            chrono::SystemClock::for_at_least(std::chrono::seconds(10));
764          ++count_;
765          total_ += packet.size();
766          PW_LOG_EVERY_N_DURATION(PW_LOG_LEVEL_DEBUG,
767                                  kLogInterval,
768                                  "Processed %zu chunks totaling %zu bytes",
769                                  count_,
770                                  total_);
771        }
772
773Log at the correct level
774------------------------
775:ref:`Log levels <module-pw_log-levels>` indicate the seriousness of a message
776and provide a simple mechanism for conditional logging and for log filtering.
777
778- **Downstream projects should use less filtered log levels**, as
779  project-specific errors more likely indicate an actionable failure.
780
781  - Use :c:macro:`PW_LOG_CRITICAL` for failures that compromise the entire
782    device and will imminently halt or crash the device.
783  - Use :c:macro:`PW_LOG_ERROR` for failures that are more serious or harder to
784    recover from.
785  - Use :c:macro:`PW_LOG_WARN` for failures that are less serious or easier to
786    recover from.
787  - Use :c:macro:`PW_LOG_INFO` for informational logs of non-failure conditions.
788
789- **Libraries and upstream code should allow configurable logging.** Downstream
790  projects may want to disable library and module logging to save on code size,
791  or enable it to aid in debugging.
792
793  - Use :c:macro:`PW_LOG_DEBUG` to log specific errors that the caller is
794    expected to handle.
795
796    .. admonition:: **Yes**
797       :class: checkmark
798
799       .. code-block:: cpp
800
801          if (stream.IsClosed()) {
802            PW_LOG_DEBUG("Stream closed unexpectedly");
803            return Status::OutOfRange();
804          }
805
806  - Use :c:macro:`PW_LOG_INFO` and :c:macro:`PW_LOG_WARN` to communicate error
807    conditions that may not have a caller that can handle them.
808
809    .. admonition:: **Yes**
810       :class: checkmark
811
812       .. code-block:: cpp
813
814          while(!task_queue_.empty()) {
815            Task task = std::move(task_queue_.back());
816            task_queue_.pop_back();
817            if (task.HasExpired()) {
818              PW_LOG_INFO("Task %zu expired before being scheduled", task.id());
819              continue;
820            }
821            Schedule(std::move(task));
822            // ...
823          }
824
825  - Set a :c:macro:`PW_LOG_LEVEL`. If logging in a module with a
826    :ref:`module configuration <module-structure-compile-time-configuration>`,
827    include a logging option and set :c:macro:`PW_LOG_LEVEL` to it.
828
829    .. admonition:: **Yes**
830       :class: checkmark
831
832       .. code-block:: cpp
833
834          // In my_module's config.h. Can be overridden at compile time.
835          #ifndef MY_MODULE_LOG_LEVEL
836          #define MY_MODULE_LOG_LEVEL PW_LOG_LEVEL_WARN
837          #endif MY_MODULE_LOG_LEVEL
838
839          // In my_module's source files.
840          #include "my_module/config.h"
841          #define PW_LOG_LEVEL MY_MODULE_LOG_LEVEL
842
843Log the right information
844-------------------------
845Logging the most useful information requires considering what may be relevant to
846an error and cannot be obtained another way.
847
848- **Include relevant context**, such as function parameters.
849- **Capitalize your log message, but do not end with puncuation.** Log backends
850  typically combine your log message with additional information and format
851  them.
852
853.. admonition:: **No**
854   :class: error
855
856   .. code-block:: cpp
857
858      PW_LOG_DEBUG("the operation did not complete normally.");
859
860.. admonition:: **Yes**
861   :class: checkmark
862
863   .. code-block:: cpp
864
865      PW_LOG_DEBUG("The operation completed normally");
866
867- **Set** :c:macro:`PW_LOG_MODULE_NAME` to include a
868  module name that you can filter on.
869
870.. admonition:: **Yes**
871   :class: checkmark
872
873   .. code-block:: cpp
874
875      #define PW_LOG_MODULE_NAME "my_module"
876
877- **Do not include source location details.** The log backend can be configured
878  to add various :ref:`module-pw_log-logging_attributes` automatically.
879
880.. admonition:: **No**
881   :class: error
882
883   .. code-block:: cpp
884
885      PW_LOG_DEBUG("%s:%d: %s called", __FILE__, __LINE__, __PRETTY_FUNCTION__);
886
887- **Do not log** :cpp:type:`pw::Status` **details.** If you are logging and
888  returning an error as a result of a subroutine that returned an error, it is
889  likely that a log statement can be added closer to where that error was
890  detected.
891
892.. admonition:: **No**
893   :class: error
894
895   .. code-block:: cpp
896
897      Result<Message> ReadAndDecode(Stream& stream) {
898        Result<EncodedMessage> result = ReadEncodedMessage(stream);
899        if (!result.ok()) {
900          Status status = result.status();
901          PW_LOG_DEBUG("Failed to read message: %s",
902                       pw_StatusString(status.code));
903          return status;
904        }
905        // ...
906      }
907
908Memory allocation
909=================
910Dynamic memory allocation can be problematic. Heap allocations and deallocations
911occupy valuable CPU cycles. Memory usage becomes nondeterministic, which can
912result in a system crashing without a clear culprit.
913
914To keep Pigweed portable, core Pigweed code is not permitted to dynamically
915(heap) allocate memory, such as with ``malloc`` or ``new``. All memory should be
916allocated with automatic (stack) or static (global) storage duration. Pigweed
917must not use C++ libraries that use dynamic allocation.
918
919Projects that use Pigweed are free to use dynamic allocation, provided they
920have selected a target that enables the heap.
921
922Naming
923======
924Entities shall be named according to the `Google style guide
925<https://google.github.io/styleguide/cppguide.html>`_, with the following
926additional requirements.
927
928C++ code
929--------
930* All Pigweed C++ code must be in the ``pw`` namespace. Namespaces for modules
931  should be nested under ``pw``. For example, ``pw::string::Format()``.
932* Whenever possible, private code should be in a source (.cc) file and placed in
933  anonymous namespace nested under ``pw``. Unit tests must be declared in an
934  anonymous namespace to avoid potential linking issues when building multiple
935  tests in one binary.
936* If private code must be exposed in a header file, it must be in a namespace
937  nested under ``pw``. The namespace may be named for its subsystem or use a
938  name that designates it as private, such as ``internal``.
939* Template arguments for non-type names (e.g. ``template <int kFooBar>``) should
940  follow the constexpr and const variable Google naming convention, which means
941  k prefixed camel case (e.g.  ``kCamelCase``). This matches the Google C++
942  style for variable naming, however the wording in the official style guide
943  isn't explicit for template arguments and could be interpreted to use
944  ``foo_bar`` style naming.  For consistency with other variables whose value is
945  always fixed for the duration of the program, the naming convention is
946  ``kCamelCase``, and so that is the style we use in Pigweed.
947* Trivial membor accessors should be named with ``snake_case()``. The Google
948  C++ style allows either ``snake_case()`` or ``CapsCase()``, but Pigweed
949  always uses ``snake_case()``.
950* Abstract base classes should be named generically, with derived types named
951  specifically. For example, ``Stream`` is an abstract base, and
952  ``SocketStream`` and ``StdioStream`` are an implementations of that
953  interface.  Any prefix or postfix indicating whether something is abstract or
954  concrete is not permitted; for example, ``IStream`` or ``SocketStreamImpl``
955  are both not permitted. These pre-/post-fixes add additional visual noise and
956  are irrelevant to consumers of these interfaces.
957
958C code
959------
960In general, C symbols should be prefixed with the module name. If the symbol is
961not associated with a module, use just ``pw`` as the module name. Facade
962backends may chose to prefix symbols with the facade's name to help reduce the
963length of the prefix.
964
965* Public names used by C code must be prefixed with the module name (e.g.
966  ``pw_tokenizer_*``).
967* If private code must be exposed in a header, private names used by C code must
968  be prefixed with an underscore followed by the module name (e.g.
969  ``_pw_assert_*``).
970* Avoid writing C source (.c) files in Pigweed. Prefer to write C++ code with C
971  linkage using ``extern "C"``. Within C source, private C functions and
972  variables must be named with the ``_pw_my_module_*`` prefix and should be
973  declared ``static`` whenever possible; for example,
974  ``_pw_my_module_MyPrivateFunction``.
975* The C prefix rules apply to
976
977  * C functions (``int pw_foo_FunctionName(void);``),
978  * variables used by C code (``int pw_foo_variable_name;``),
979  * constant variables used by C code (``const int pw_foo_kConstantName;``),
980  * structs used by C code (``typedef struct {} pw_foo_StructName;``), and
981  * all of the above for ``extern "C"`` names in C++ code.
982
983  The prefix does not apply to struct members, which use normal Google style.
984
985Preprocessor macros
986-------------------
987* Public Pigweed macros must be prefixed with the module name (e.g.
988  ``PW_MY_MODULE_*``).
989* Private Pigweed macros must be prefixed with an underscore followed by the
990  module name (e.g. ``_PW_MY_MODULE_*``). (This style may change, see
991  `b/234886184 <https://issuetracker.google.com/issues/234886184>`_).
992
993**Example**
994
995.. code-block:: cpp
996
997   namespace pw::my_module {
998   namespace nested_namespace {
999
1000   // C++ names (types, variables, functions) must be in the pw namespace.
1001   // They are named according to the Google style guide.
1002   constexpr int kGlobalConstant = 123;
1003
1004   // Prefer using functions over extern global variables.
1005   extern int global_variable;
1006
1007   class Class {};
1008
1009   void Function();
1010
1011   extern "C" {
1012
1013   // Public Pigweed code used from C must be prefixed with pw_.
1014   extern const int pw_my_module_kGlobalConstant;
1015
1016   extern int pw_my_module_global_variable;
1017
1018   void pw_my_module_Function(void);
1019
1020   typedef struct {
1021     int member_variable;
1022   } pw_my_module_Struct;
1023
1024   // Private Pigweed code used from C must be prefixed with _pw_.
1025   extern const int _pw_my_module_kPrivateGlobalConstant;
1026
1027   extern int _pw_my_module_private_global_variable;
1028
1029   void _pw_my_module_PrivateFunction(void);
1030
1031   typedef struct {
1032     int member_variable;
1033   } _pw_my_module_PrivateStruct;
1034
1035   }  // extern "C"
1036
1037   // Public macros must be prefixed with PW_.
1038   #define PW_MY_MODULE_PUBLIC_MACRO(arg) arg
1039
1040   // Private macros must be prefixed with _PW_.
1041   #define _PW_MY_MODULE_PRIVATE_MACRO(arg) arg
1042
1043   }  // namespace nested_namespace
1044   }  // namespace pw::my_module
1045
1046See :ref:`docs-pw-style-macros` for details about macro usage.
1047
1048Namespace scope formatting
1049==========================
1050All non-indented blocks (namespaces, ``extern "C"`` blocks, and preprocessor
1051conditionals) must have a comment on their closing line with the
1052contents of the starting line.
1053
1054All nested namespaces should be declared together with no blank lines between
1055them.
1056
1057.. code-block:: cpp
1058
1059   #include "some/header.h"
1060
1061   namespace pw::nested {
1062   namespace {
1063
1064   constexpr int kAnonConstantGoesHere = 0;
1065
1066   }  // namespace
1067
1068   namespace other {
1069
1070   const char* SomeClass::yes = "no";
1071
1072   bool ThisIsAFunction() {
1073   #if PW_CONFIG_IS_SET
1074     return true;
1075   #else
1076     return false;
1077   #endif  // PW_CONFIG_IS_SET
1078   }
1079
1080   extern "C" {
1081
1082   const int pw_kSomeConstant = 10;
1083   int pw_some_global_variable = 600;
1084
1085   void pw_CFunction() { ... }
1086
1087   }  // extern "C"
1088
1089   }  // namespace
1090   }  // namespace pw::nested
1091
1092Using directives for literals
1093=============================
1094`Using-directives
1095<https://en.cppreference.com/w/cpp/language/namespace#Using-directives>`_ (e.g.
1096``using namespace ...``) are permitted in implementation files only for the
1097purposes of importing literals such as ``std::chrono_literals`` or
1098``pw::bytes::unit_literals``. Namespaces that contain any symbols other than
1099literals are not permitted in a using-directive. This guidance also has no
1100impact on `using-declarations
1101<https://en.cppreference.com/w/cpp/language/namespace#Using-declarations>`_
1102(e.g. ``using foo::Bar;``).
1103
1104Rationale: Literals improve code readability, making units clearer at the point
1105of definition.
1106
1107.. code-block:: cpp
1108
1109   using namespace std::chrono;                    // Not allowed
1110   using namespace std::literals::chrono_literals; // Allowed
1111
1112   constexpr std::chrono::duration delay = 250ms;
1113
1114Pointers and references
1115=======================
1116For pointer and reference types, place the asterisk or ampersand next to the
1117type.
1118
1119.. code-block:: cpp
1120
1121   int* const number = &that_thing;
1122   constexpr const char* kString = "theory!"
1123
1124   bool FindTheOneRing(const Region& where_to_look) { ... }
1125
1126Prefer storing references over storing pointers. Pointers are required when the
1127pointer can change its target or may be ``nullptr``. Otherwise, a reference or
1128const reference should be used.
1129
1130.. _docs-pw-style-macros:
1131
1132Preprocessor macros
1133===================
1134Macros should only be used when they significantly improve upon the C++ code
1135they replace. Macros should make code more readable, robust, and safe, or
1136provide features not possible with standard C++, such as stringification, line
1137number capturing, or conditional compilation. When possible, use C++ constructs
1138like constexpr variables in place of macros. Never use macros as constants,
1139except when a string literal is needed or the value must be used by C code.
1140
1141When macros are needed, the macros should be accompanied with extensive tests
1142to ensure the macros are hard to use wrong.
1143
1144Stand-alone statement macros
1145----------------------------
1146Macros that are standalone statements must require the caller to terminate the
1147macro invocation with a semicolon (see `Swalling the Semicolon
1148<https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html>`_). For
1149example, the following does *not* conform to Pigweed's macro style:
1150
1151.. code-block:: cpp
1152
1153   // BAD! Definition has built-in semicolon.
1154   #define PW_LOG_IF_BAD(mj) \
1155     CallSomeFunction(mj);
1156
1157   // BAD! Compiles without error; semicolon is missing.
1158   PW_LOG_IF_BAD("foo")
1159
1160Here's how to do this instead:
1161
1162.. code-block:: cpp
1163
1164   // GOOD; requires semicolon to compile.
1165   #define PW_LOG_IF_BAD(mj) \
1166     CallSomeFunction(mj)
1167
1168   // GOOD; fails to compile due to lacking semicolon.
1169   PW_LOG_IF_BAD("foo")
1170
1171For macros in function scope that do not already require a semicolon, the
1172contents can be placed in a ``do { ... } while (0)`` loop.
1173
1174.. code-block:: cpp
1175
1176   #define PW_LOG_IF_BAD(mj)  \
1177     do {                     \
1178       if (mj.Bad()) {        \
1179         Log(#mj " is bad")   \
1180       }                      \
1181     } while (0)
1182
1183Standalone macros at global scope that do not already require a semicolon can
1184add a ``static_assert`` declaration statement as their last line.
1185
1186.. code-block:: cpp
1187
1188   #define PW_NEAT_THING(thing)             \
1189     bool IsNeat_##thing() { return true; } \
1190     static_assert(true, "Macros must be terminated with a semicolon")
1191
1192Private macros in public headers
1193--------------------------------
1194Private macros in public headers must be prefixed with ``_PW_``, even if they
1195are undefined after use; this prevents collisions with downstream users. For
1196example:
1197
1198.. code-block:: cpp
1199
1200   #define _PW_MY_SPECIAL_MACRO(op) ...
1201   ...
1202   // Code that uses _PW_MY_SPECIAL_MACRO()
1203   ...
1204   #undef _PW_MY_SPECIAL_MACRO
1205
1206Macros in private implementation files (.cc)
1207--------------------------------------------
1208Macros within .cc files that should only be used within one file should be
1209undefined after their last use; for example:
1210
1211.. code-block:: cpp
1212
1213   #define DEFINE_OPERATOR(op) \
1214     T operator ## op(T x, T y) { return x op y; } \
1215     static_assert(true, "Macros must be terminated with a semicolon") \
1216
1217   DEFINE_OPERATOR(+);
1218   DEFINE_OPERATOR(-);
1219   DEFINE_OPERATOR(/);
1220   DEFINE_OPERATOR(*);
1221
1222   #undef DEFINE_OPERATOR
1223
1224Preprocessor conditional statements
1225===================================
1226When using macros for conditional compilation, prefer to use ``#if`` over
1227``#ifdef``. This checks the value of the macro rather than whether it exists.
1228
1229* ``#if`` handles undefined macros equivalently to ``#ifdef``. Undefined
1230  macros expand to 0 in preprocessor conditional statements.
1231* ``#if`` evaluates false for macros defined as 0, while ``#ifdef`` evaluates
1232  true.
1233* Macros defined using compiler flags have a default value of 1 in GCC and
1234  Clang, so they work equivalently for ``#if`` and ``#ifdef``.
1235* Macros defined to an empty statement cause compile-time errors in ``#if``
1236  statements, which avoids ambiguity about how the macro should be used.
1237
1238All ``#endif`` statements should be commented with the expression from their
1239corresponding ``#if``. Do not indent within preprocessor conditional statements.
1240
1241.. code-block:: cpp
1242
1243   #if USE_64_BIT_WORD
1244   using Word = uint64_t;
1245   #else
1246   using Word = uint32_t;
1247   #endif  // USE_64_BIT_WORD
1248
1249Unsigned integers
1250=================
1251Unsigned integers are permitted in Pigweed. Aim for consistency with existing
1252code and the C++ Standard Library. Be very careful mixing signed and unsigned
1253integers.
1254
1255Features not in the C++ standard
1256================================
1257Avoid features not available in standard C++. This includes compiler extensions
1258and features from other standards like POSIX.
1259
1260For example, use ``ptrdiff_t`` instead of POSIX's ``ssize_t``, unless
1261interacting with a POSIX API in intentionally non-portable code. Never use
1262POSIX functions with suitable standard or Pigweed alternatives, such as
1263``strnlen`` (use ``pw::string::NullTerminatedLength`` instead).
1264