1*61c4878aSAndroid Build Coastguard Worker.. _docs-embedded-cpp: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker================== 4*61c4878aSAndroid Build Coastguard WorkerEmbedded C++ Guide 5*61c4878aSAndroid Build Coastguard Worker================== 6*61c4878aSAndroid Build Coastguard Worker 7*61c4878aSAndroid Build Coastguard WorkerThis page contains recommendations for using C++ for embedded software. For 8*61c4878aSAndroid Build Coastguard WorkerPigweed code, these should be considered as requirements. For external 9*61c4878aSAndroid Build Coastguard Workerprojects, these recommendations can serve as a resource for efficiently using 10*61c4878aSAndroid Build Coastguard WorkerC++ in embedded projects. 11*61c4878aSAndroid Build Coastguard Worker 12*61c4878aSAndroid Build Coastguard WorkerThese recommendations are subject to change as the C++ standard and compilers 13*61c4878aSAndroid Build Coastguard Workerevolve, and as the authors continue to gain more knowledge and experience in 14*61c4878aSAndroid Build Coastguard Workerthis area. If you disagree with recommendations, please discuss them with the 15*61c4878aSAndroid Build Coastguard WorkerPigweed team, as we're always looking to improve the guide or correct any 16*61c4878aSAndroid Build Coastguard Workerinaccuracies. 17*61c4878aSAndroid Build Coastguard Worker 18*61c4878aSAndroid Build Coastguard WorkerConstexpr functions 19*61c4878aSAndroid Build Coastguard Worker=================== 20*61c4878aSAndroid Build Coastguard WorkerConstexpr functions are functions that may be called from a constant 21*61c4878aSAndroid Build Coastguard Workerexpression, such as a template parameter, constexpr variable initialization, or 22*61c4878aSAndroid Build Coastguard Worker``static_assert`` statement. Labeling a function ``constexpr`` does not 23*61c4878aSAndroid Build Coastguard Workerguarantee that it is executed at compile time; if called from regular code, it 24*61c4878aSAndroid Build Coastguard Workerwill be compiled as a regular function and executed at run time. 25*61c4878aSAndroid Build Coastguard Worker 26*61c4878aSAndroid Build Coastguard WorkerConstexpr functions are implicitly inline, which means they are suitable to be 27*61c4878aSAndroid Build Coastguard Workerdefined in header files. Like any function in a header, the compiler is more 28*61c4878aSAndroid Build Coastguard Workerlikely to inline it than other functions. Marking non-trivial functions as 29*61c4878aSAndroid Build Coastguard Worker``constexpr`` could increase code size, so check the compilation results if this 30*61c4878aSAndroid Build Coastguard Workeris a concern. 31*61c4878aSAndroid Build Coastguard Worker 32*61c4878aSAndroid Build Coastguard WorkerSimple constructors should be marked ``constexpr`` whenever possible. GCC 33*61c4878aSAndroid Build Coastguard Workerproduces smaller code in some situations when the ``constexpr`` specifier is 34*61c4878aSAndroid Build Coastguard Workerpresent. Do not avoid important initialization in order to make the class 35*61c4878aSAndroid Build Coastguard Workerconstexpr-constructible unless it actually needs to be used in a constant 36*61c4878aSAndroid Build Coastguard Workerexpression. 37*61c4878aSAndroid Build Coastguard Worker 38*61c4878aSAndroid Build Coastguard WorkerConstexpr variables 39*61c4878aSAndroid Build Coastguard Worker=================== 40*61c4878aSAndroid Build Coastguard WorkerConstants should be marked ``constexpr`` whenever possible. Constexpr variables 41*61c4878aSAndroid Build Coastguard Workercan be used in any constant expression, such as a non-type template argument, 42*61c4878aSAndroid Build Coastguard Worker``static_assert`` statement, or another constexpr variable initialization. 43*61c4878aSAndroid Build Coastguard WorkerConstexpr variables can be initialized at compile time with values calculated by 44*61c4878aSAndroid Build Coastguard Workerconstexpr functions. 45*61c4878aSAndroid Build Coastguard Worker 46*61c4878aSAndroid Build Coastguard Worker``constexpr`` implies ``const`` for variables, so there is no need to include 47*61c4878aSAndroid Build Coastguard Workerthe ``const`` qualifier when declaring a constexpr variable. 48*61c4878aSAndroid Build Coastguard Worker 49*61c4878aSAndroid Build Coastguard WorkerUnlike constexpr functions, constexpr variables are **not** implicitly inline. 50*61c4878aSAndroid Build Coastguard WorkerConstexpr variables in headers must be declared with the ``inline`` specifier. 51*61c4878aSAndroid Build Coastguard Worker 52*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 53*61c4878aSAndroid Build Coastguard Worker 54*61c4878aSAndroid Build Coastguard Worker namespace pw { 55*61c4878aSAndroid Build Coastguard Worker 56*61c4878aSAndroid Build Coastguard Worker inline constexpr const char* kStringConstant = "O_o"; 57*61c4878aSAndroid Build Coastguard Worker 58*61c4878aSAndroid Build Coastguard Worker inline constexpr float kFloatConstant1 = CalculateFloatConstant(1); 59*61c4878aSAndroid Build Coastguard Worker inline constexpr float kFloatConstant2 = CalculateFloatConstant(2); 60*61c4878aSAndroid Build Coastguard Worker 61*61c4878aSAndroid Build Coastguard Worker } // namespace pw 62*61c4878aSAndroid Build Coastguard Worker 63*61c4878aSAndroid Build Coastguard WorkerFunction templates 64*61c4878aSAndroid Build Coastguard Worker================== 65*61c4878aSAndroid Build Coastguard WorkerFunction templates facilitate writing code that works with different types. For 66*61c4878aSAndroid Build Coastguard Workerexample, the following clamps a value within a minimum and maximum: 67*61c4878aSAndroid Build Coastguard Worker 68*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 69*61c4878aSAndroid Build Coastguard Worker 70*61c4878aSAndroid Build Coastguard Worker template <typename T> 71*61c4878aSAndroid Build Coastguard Worker T Clamp(T min, T max, T value) { 72*61c4878aSAndroid Build Coastguard Worker if (value < min) { 73*61c4878aSAndroid Build Coastguard Worker return min; 74*61c4878aSAndroid Build Coastguard Worker } 75*61c4878aSAndroid Build Coastguard Worker if (value > max) { 76*61c4878aSAndroid Build Coastguard Worker return max; 77*61c4878aSAndroid Build Coastguard Worker } 78*61c4878aSAndroid Build Coastguard Worker return value; 79*61c4878aSAndroid Build Coastguard Worker } 80*61c4878aSAndroid Build Coastguard Worker 81*61c4878aSAndroid Build Coastguard WorkerThe above code works seamlessly with values of any type -- float, int, or even a 82*61c4878aSAndroid Build Coastguard Workercustom type that supports the < and > operators. 83*61c4878aSAndroid Build Coastguard Worker 84*61c4878aSAndroid Build Coastguard WorkerThe compiler implements templates by generating a separate version of the 85*61c4878aSAndroid Build Coastguard Workerfunction for each set of types it is instantiated with. This can increase code 86*61c4878aSAndroid Build Coastguard Workersize significantly. 87*61c4878aSAndroid Build Coastguard Worker 88*61c4878aSAndroid Build Coastguard Worker.. tip:: 89*61c4878aSAndroid Build Coastguard Worker 90*61c4878aSAndroid Build Coastguard Worker Be careful when instantiating non-trivial template functions with multiple 91*61c4878aSAndroid Build Coastguard Worker types. 92*61c4878aSAndroid Build Coastguard Worker 93*61c4878aSAndroid Build Coastguard WorkerVirtual functions 94*61c4878aSAndroid Build Coastguard Worker================= 95*61c4878aSAndroid Build Coastguard WorkerVirtual functions provide for runtime polymorphism. Unless runtime polymorphism 96*61c4878aSAndroid Build Coastguard Workeris required, virtual functions should be avoided. Virtual functions require a 97*61c4878aSAndroid Build Coastguard Workervirtual table, which increases RAM usage and requires extra instructions at each 98*61c4878aSAndroid Build Coastguard Workercall site. Virtual functions can also inhibit compiler optimizations, since the 99*61c4878aSAndroid Build Coastguard Workercompiler may not be able to tell which functions will actually be invoked. This 100*61c4878aSAndroid Build Coastguard Workercan prevent linker garbage collection, resulting in unused functions being 101*61c4878aSAndroid Build Coastguard Workerlinked into a binary. 102*61c4878aSAndroid Build Coastguard Worker 103*61c4878aSAndroid Build Coastguard WorkerWhen runtime polymorphism is required, virtual functions should be considered. 104*61c4878aSAndroid Build Coastguard WorkerC alternatives, such as a struct of function pointers, could be used instead, 105*61c4878aSAndroid Build Coastguard Workerbut these approaches may offer no performance advantage while sacrificing 106*61c4878aSAndroid Build Coastguard Workerflexibility and ease of use. 107*61c4878aSAndroid Build Coastguard Worker 108*61c4878aSAndroid Build Coastguard Worker.. tip:: 109*61c4878aSAndroid Build Coastguard Worker 110*61c4878aSAndroid Build Coastguard Worker Only use virtual functions when runtime polymorphism is needed. 111*61c4878aSAndroid Build Coastguard Worker 112*61c4878aSAndroid Build Coastguard WorkerCompiler warnings 113*61c4878aSAndroid Build Coastguard Worker================= 114*61c4878aSAndroid Build Coastguard WorkerBugs in embedded systems can be difficult to track down. Compiler warnings are 115*61c4878aSAndroid Build Coastguard Workerone tool to help identify and fix bugs early in development. 116*61c4878aSAndroid Build Coastguard Worker 117*61c4878aSAndroid Build Coastguard WorkerPigweed compiles with a strict set of warnings. The warnings include the 118*61c4878aSAndroid Build Coastguard Workerfollowing: 119*61c4878aSAndroid Build Coastguard Worker 120*61c4878aSAndroid Build Coastguard Worker* ``-Wall`` and ``-Wextra`` -- Standard sets of compilation warnings, which 121*61c4878aSAndroid Build Coastguard Worker are recommended for all projects. 122*61c4878aSAndroid Build Coastguard Worker* ``-Wimplicit-fallthrough`` -- Requires explicit ``[[fallthrough]]`` 123*61c4878aSAndroid Build Coastguard Worker annotations for fallthrough between switch cases. Prevents unintentional 124*61c4878aSAndroid Build Coastguard Worker fallthroughs if a ``break`` or ``return`` is forgotten. 125*61c4878aSAndroid Build Coastguard Worker* ``-Wundef`` -- Requires macros to be defined before using them. This 126*61c4878aSAndroid Build Coastguard Worker disables the standard, problematic behavior that replaces undefined (or 127*61c4878aSAndroid Build Coastguard Worker misspelled) macros with ``0``. 128*61c4878aSAndroid Build Coastguard Worker 129*61c4878aSAndroid Build Coastguard WorkerUnused variable and function warnings 130*61c4878aSAndroid Build Coastguard Worker------------------------------------- 131*61c4878aSAndroid Build Coastguard WorkerThe ``-Wall`` and ``-Wextra`` flags enable warnings about unused variables or 132*61c4878aSAndroid Build Coastguard Workerfunctions. Usually, the best way to address these warnings is to remove the 133*61c4878aSAndroid Build Coastguard Workerunused items. In some circumstances, these cannot be removed, so the warning 134*61c4878aSAndroid Build Coastguard Workermust be silenced. This is done in one of the following ways: 135*61c4878aSAndroid Build Coastguard Worker 136*61c4878aSAndroid Build Coastguard Worker1. When possible, delete unused variables, functions, or class definitions. 137*61c4878aSAndroid Build Coastguard Worker2. If an unused entity must remain in the code, avoid giving it a name. A 138*61c4878aSAndroid Build Coastguard Worker common situation that triggers unused parameter warnings is implementing a 139*61c4878aSAndroid Build Coastguard Worker virtual function or callback. In C++, function parameters may be unnamed. 140*61c4878aSAndroid Build Coastguard Worker If desired, the variable name can remain in the code as a comment. 141*61c4878aSAndroid Build Coastguard Worker 142*61c4878aSAndroid Build Coastguard Worker .. code-block:: cpp 143*61c4878aSAndroid Build Coastguard Worker 144*61c4878aSAndroid Build Coastguard Worker class BaseCalculator { 145*61c4878aSAndroid Build Coastguard Worker public: 146*61c4878aSAndroid Build Coastguard Worker virtual int DoMath(int number_1, int number_2, int number_3) = 0; 147*61c4878aSAndroid Build Coastguard Worker }; 148*61c4878aSAndroid Build Coastguard Worker 149*61c4878aSAndroid Build Coastguard Worker class Calculator : public BaseCalculator { 150*61c4878aSAndroid Build Coastguard Worker int DoMath(int number_1, int /* number_2 */, int) override { 151*61c4878aSAndroid Build Coastguard Worker return number_1 * 100; 152*61c4878aSAndroid Build Coastguard Worker } 153*61c4878aSAndroid Build Coastguard Worker }; 154*61c4878aSAndroid Build Coastguard Worker 155*61c4878aSAndroid Build Coastguard Worker3. In C++, annotate unused entities with `[[maybe_unused]] 156*61c4878aSAndroid Build Coastguard Worker <https://en.cppreference.com/w/cpp/language/attributes/maybe_unused>`_ to 157*61c4878aSAndroid Build Coastguard Worker silence warnings. 158*61c4878aSAndroid Build Coastguard Worker 159*61c4878aSAndroid Build Coastguard Worker .. code-block:: cpp 160*61c4878aSAndroid Build Coastguard Worker 161*61c4878aSAndroid Build Coastguard Worker // This variable is unused in certain circumstances. 162*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] int expected_size = size * 4; 163*61c4878aSAndroid Build Coastguard Worker #if OPTION_1 164*61c4878aSAndroid Build Coastguard Worker DoThing1(expected_size); 165*61c4878aSAndroid Build Coastguard Worker #elif OPTION_2 166*61c4878aSAndroid Build Coastguard Worker DoThing2(expected_size); 167*61c4878aSAndroid Build Coastguard Worker #endif 168*61c4878aSAndroid Build Coastguard Worker 169*61c4878aSAndroid Build Coastguard Worker4. As a final option, cast unused variables to ``void`` to silence these 170*61c4878aSAndroid Build Coastguard Worker warnings. Use ``static_cast<void>(unused_var)`` in C++ or 171*61c4878aSAndroid Build Coastguard Worker ``(void)unused_var`` in C. 172*61c4878aSAndroid Build Coastguard Worker 173*61c4878aSAndroid Build Coastguard Worker In C, silencing warnings on unused functions may require compiler-specific 174*61c4878aSAndroid Build Coastguard Worker attributes (``__attribute__((unused))``). Avoid this by removing the 175*61c4878aSAndroid Build Coastguard Worker functions or compiling with C++ and using ``[[maybe_unused]]``. 176*61c4878aSAndroid Build Coastguard Worker 177*61c4878aSAndroid Build Coastguard WorkerDealing with ``nodiscard`` return values 178*61c4878aSAndroid Build Coastguard Worker---------------------------------------- 179*61c4878aSAndroid Build Coastguard WorkerThere are rare circumstances where a ``nodiscard`` return value from a function 180*61c4878aSAndroid Build Coastguard Workercall needs to be discarded. For ``pw::Status`` value ``.IgnoreError()`` can be 181*61c4878aSAndroid Build Coastguard Workerappended to the the function call. For other instances, ``std::ignore`` can be 182*61c4878aSAndroid Build Coastguard Workerused. 183*61c4878aSAndroid Build Coastguard Worker 184*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 185*61c4878aSAndroid Build Coastguard Worker 186*61c4878aSAndroid Build Coastguard Worker // <tuple> defines std::ignore. 187*61c4878aSAndroid Build Coastguard Worker #include <tuple> 188*61c4878aSAndroid Build Coastguard Worker 189*61c4878aSAndroid Build Coastguard Worker DoThingWithStatus().IgnoreError(); 190*61c4878aSAndroid Build Coastguard Worker std::ignore = DoThingWithReturnValue(); 191