1.. _module-pw_preprocessor: 2 3--------------- 4pw_preprocessor 5--------------- 6The preprocessor module provides various helpful preprocessor macros. 7 8Compatibility 9============= 10C and C++ 11 12Headers 13======= 14The preprocessor module provides several headers. 15 16pw_preprocessor/arguments.h 17--------------------------------- 18Defines macros for handling variadic arguments to function-like macros. Macros 19include the following: 20 21.. c:macro:: PW_DELEGATE_BY_ARG_COUNT(name, ...) 22 23 Selects and invokes a macro based on the number of arguments provided. Expands 24 to ``<name><arg_count>(...)``. For example, 25 ``PW_DELEGATE_BY_ARG_COUNT(foo_, 1, 2, 3)`` expands to ``foo_3(1, 2, 3)``. 26 27 This example shows how ``PW_DELEGATE_BY_ARG_COUNT`` could be used to log a 28 customized message based on the number of arguments provided. 29 30 .. code-block:: cpp 31 32 #define ARG_PRINT(...) PW_DELEGATE_BY_ARG_COUNT(_ARG_PRINT, __VA_ARGS__) 33 #define _ARG_PRINT0(a) LOG_INFO("nothing!") 34 #define _ARG_PRINT1(a) LOG_INFO("1 arg: %s", a) 35 #define _ARG_PRINT2(a, b) LOG_INFO("2 args: %s, %s", a, b) 36 #define _ARG_PRINT3(a, b, c) LOG_INFO("3 args: %s, %s, %s", a, b, c) 37 38 When used, ``ARG_PRINT`` expands to the ``_ARG_PRINT#`` macro corresponding 39 to the number of arguments. 40 41 .. code-block:: cpp 42 43 ARG_PRINT(); // Outputs: nothing! 44 ARG_PRINT("a"); // Outputs: 1 arg: a 45 ARG_PRINT("a", "b"); // Outputs: 2 args: a, b 46 ARG_PRINT("a", "b", "c"); // Outputs: 3 args: a, b, c 47 48.. c:macro:: PW_COMMA_ARGS(...) 49 50 Expands to a comma followed by the arguments if any arguments are provided. 51 Otherwise, expands to nothing. If the final argument is empty, it is omitted. 52 This is useful when passing ``__VA_ARGS__`` to a variadic function or template 53 parameter list, since it removes the extra comma when no arguments are 54 provided. ``PW_COMMA_ARGS`` must NOT be used when invoking a macro from 55 another macro. 56 57 For example. ``PW_COMMA_ARGS(1, 2, 3)``, expands to ``, 1, 2, 3``, while 58 ``PW_COMMA_ARGS()`` expands to nothing. ``PW_COMMA_ARGS(1, 2, )`` expands to 59 ``, 1, 2``. 60 61pw_preprocessor/boolean.h 62------------------------- 63Defines macros for boolean logic on literal 1s and 0s. This is useful for 64situations when a literal is needed to build the name of a function or macro. 65 66pw_preprocessor/compiler.h 67-------------------------- 68Macros for compiler-specific features, such as attributes or builtins. 69 70.. c:macro:: PW_PACKED(declaration) 71 72 Marks a struct or class as packed. 73 74.. c:macro:: PW_USED 75 76 Marks a function or object as used, ensuring code for it is generated. 77 78.. c:macro:: PW_NO_PROLOGUE 79 80 Prevents generation of a prologue or epilogue for a function. This is 81 helpful when implementing the function in assembly. 82 83.. c:macro:: PW_PRINTF_FORMAT(format_index, parameter_index) 84 85 Marks that a function declaration takes a printf-style format string and 86 variadic arguments. This allows the compiler to perform check the validity of 87 the format string and arguments. This macro must only be on the function 88 declaration, not the definition. 89 90 The format_index is index of the format string parameter and parameter_index 91 is the starting index of the variadic arguments. Indices start at 1. For C++ 92 class member functions, add one to the index to account for the implicit this 93 parameter. 94 95 This example shows a function where the format string is argument 2 and the 96 varargs start at argument 3. 97 98 .. code-block:: cpp 99 100 int PrintfStyleFunction(char* buffer, 101 const char* fmt, ...) PW_PRINTF_FORMAT(2,3); 102 103 int PrintfStyleFunction(char* buffer, const char* fmt, ...) { 104 ... implementation here ... 105 } 106 107.. c:macro:: PW_PLACE_IN_SECTION(name) 108 109 Places a variable in the specified linker section. 110 111.. c:macro:: PW_KEEP_IN_SECTION(name) 112 113 Places a variable in the specified linker section and directs the compiler 114 to keep the variable, even if it is not used. Depending on the linker 115 options, the linker may still remove this section if it is not declared in 116 the linker script and marked KEEP. 117 118.. c:macro:: PW_NO_RETURN 119 120 Indicate to the compiler that the annotated function won't return. Example: 121 122 .. code-block:: cpp 123 124 PW_NO_RETURN void HandleAssertFailure(ErrorCode error_code); 125 126 127.. c:macro:: PW_NO_INLINE 128 129 Prevents the compiler from inlining a fuction. 130 131.. c:macro:: PW_UNREACHABLE 132 133 Indicate to the compiler that the given section of code will not be reached. 134 Example: 135 136 .. code-block:: cpp 137 138 int main() { 139 InitializeBoard(); 140 vendor_StartScheduler(); // Note: vendor forgot noreturn attribute. 141 PW_UNREACHABLE; 142 } 143 144 145.. c:macro:: PW_NO_SANITIZE(check) 146 147 Indicate to a sanitizer compiler runtime to skip the named check in the 148 associated function. 149 Example: 150 151 .. code-block:: cpp 152 153 uint32_t djb2(const void* buf, size_t len) 154 PW_NO_SANITIZE("unsigned-integer-overflow"){ 155 uint32_t hash = 5381; 156 const uint8_t* u8 = static_cast<const uint8_t*>(buf); 157 for (size_t i = 0; i < len; ++i) { 158 hash = (hash * 33) + u8[i]; // hash * 33 + c 159 } 160 return hash; 161 } 162 163.. c:macro:: PW_HAVE_ATTRIBUTE(x) 164 165 Wrapper around `__has_attribute`, which is defined by GCC 5+ and Clang and 166 evaluates to a non zero constant integer if the attribute is supported or 0 167 if not. 168 169.. c:macro:: PW_HAVE_CPP_ATTRIBUTE(x) 170 171 Wrapper around `__has_cpp_attribute`, which was introduced in the C++20 172 standard. It is supported by compilers even if C++20 is not in use. Evaluates 173 to a non zero constant integer if the C++ attribute is supported or 0 if not. 174 175.. c:macro:: PW_PRAGMA(contents) 176 177 Expands to a _Pragma with the contents as a string. _Pragma must take a 178 single string literal; this can be used to construct a _Pragma argument. 179 180.. c:macro:: PW_WEAK 181 182 Marks a function or object as weak, allowing the definition to be overriden. 183 184 This can be useful when supporting third-party SDKs which may conditionally 185 compile in code, for example: 186 187 .. code-block:: cpp 188 189 PW_WEAK void SysTick_Handler(void) { 190 // Default interrupt handler that might be overriden. 191 } 192 193.. c:macro:: PW_ALIAS(aliased_to) 194 195 Marks a weak function as an alias to another, allowing the definition to 196 be given a default and overriden. 197 198 This can be useful when supporting third-party SDKs which may conditionally 199 compile in code, for example: 200 201 .. code-block:: cpp 202 203 // Driver handler replaced with default unless overridden. 204 void USART_DriverHandler(void) PW_ALIAS(DefaultDriverHandler); 205 206.. c:macro:: PW_ATTRIBUTE_LIFETIME_BOUND 207 208 PW_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function 209 parameter or implicit object parameter is retained by the return value of the 210 annotated function (or, for a parameter of a constructor, in the value of the 211 constructed object). This attribute causes warnings to be produced if a 212 temporary object does not live long enough. 213 214 When applied to a reference parameter, the referenced object is assumed to be 215 retained by the return value of the function. When applied to a non-reference 216 parameter (for example, a pointer or a class type), all temporaries 217 referenced by the parameter are assumed to be retained by the return value of 218 the function. 219 220 See also the upstream documentation: 221 https://clang.llvm.org/docs/AttributeReference.html#lifetimebound 222 223 This is a copy of ABSL_ATTRIBUTE_LIFETIME_BOUND. 224 225Modifying compiler diagnostics 226^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 227``pw_preprocessor/compiler.h`` provides macros for enabling or disabling 228compiler diagnostics (warnings or errors). 229 230.. c:macro:: PW_MODIFY_DIAGNOSTICS_PUSH() 231 232 Starts a new group of :c:macro:`PW_MODIFY_DIAGNOSTIC` statements. A 233 :c:macro:`PW_MODIFY_DIAGNOSTICS_POP` statement must follow. 234 235.. c:macro:: PW_MODIFY_DIAGNOSTICS_POP() 236 237 :c:macro:`PW_MODIFY_DIAGNOSTIC` statements since the most recent 238 :c:macro:`PW_MODIFY_DIAGNOSTICS_PUSH` no longer apply after this statement. 239 240.. c:macro:: PW_MODIFY_DIAGNOSTIC(kind, option) 241 242 Changes how a diagnostic (warning or error) is handled. Most commonly used to 243 disable warnings. ``PW_MODIFY_DIAGNOSTIC`` should be used between 244 :c:macro:`PW_MODIFY_DIAGNOSTICS_PUSH` and :c:macro:`PW_MODIFY_DIAGNOSTICS_POP` 245 statements to avoid applying the modifications too broadly. 246 247 ``kind`` may be ``warning``, ``error``, or ``ignored``. 248 249These macros can be used to disable warnings for precise sections of code, even 250a single line if necessary. 251 252.. code-block:: c 253 254 PW_MODIFY_DIAGNOSTICS_PUSH(); 255 PW_MODIFY_DIAGNOSTIC(ignored, "-Wunused-variable"); 256 257 static int this_variable_is_never_used; 258 259 PW_MODIFY_DIAGNOSTICS_POP(); 260 261.. tip:: 262 263 :c:macro:`PW_MODIFY_DIAGNOSTIC` and related macros should rarely be used. 264 Whenever possible, fix the underlying issues about which the compiler is 265 warning, rather than silencing the diagnostics. 266 267pw_preprocessor/concat.h 268------------------------ 269Defines the ``PW_CONCAT(...)`` macro, which expands its arguments if they are 270macros and token pastes the results. This can be used for building names of 271classes, variables, macros, etc. 272 273pw_preprocessor/util.h 274---------------------- 275General purpose, useful macros. 276 277* ``PW_ARRAY_SIZE(array)`` -- calculates the size of a C array 278* ``PW_STRINGIFY(...)`` -- expands its arguments as macros and converts them to 279 a string literal 280* ``PW_EXTERN_C`` -- declares a name to be ``extern "C"`` in C++; expands to 281 nothing in C 282* ``PW_EXTERN_C_START`` / ``PW_EXTERN_C_END`` -- declares an ``extern "C" { }`` 283 block in C++; expands to nothing in C 284 285Zephyr 286====== 287To enable ``pw_preprocessor`` for Zephyr add ``CONFIG_PIGWEED_PREPROCESSOR=y`` 288to the project's configuration. 289