|
35 | 35 | [completely different](https://www.kernel.org/doc/html/latest/process/coding-style.html#typedefs) |
36 | 36 | (see below) (BTW: Do we have any reason to do so?) |
37 | 37 | * Comments should be C-style comments (see below) |
38 | | -* In order to follow Linux's recommendation on |
39 | | - [conditional compilation](https://www.kernel.org/doc/html/latest/process/coding-style.html#conditional-compilation) |
40 | | - make use of `IS_ACTIVE` and `IS_USED` macros from `kernel_defines.h` with C |
41 | | - conditionals. If a symbol is not going to be defined under a certain |
42 | | - condition, the usage of preprocessor `#if defined()` is fine. |
43 | 38 | * You can use [uncrustify](http://uncrustify.sourceforge.net/) with the provided |
44 | 39 | option files: https://github.com/RIOT-OS/RIOT/blob/master/uncrustify-riot.cfg |
45 | 40 |
|
@@ -209,6 +204,113 @@ of recognised exceptions where we can (or even must) rely on extensions include: |
209 | 204 | } |
210 | 205 | ``` |
211 | 206 |
|
| 207 | +### Conditional Compilation |
| 208 | + |
| 209 | +In order to follow Linux's recommendation on |
| 210 | +[conditional compilation](https://www.kernel.org/doc/html/latest/process/coding-style.html#conditional-compilation) |
| 211 | +make use of `IS_ACTIVE` and `IS_USED` macros from `kernel_defines.h` with C |
| 212 | +conditionals. |
| 213 | +If a symbol is not going to be defined under a certain condition, |
| 214 | +the usage of preprocessor `#if defined()` is fine. |
| 215 | + |
| 216 | +Optional branches in C code should use macros instead of preprocessor |
| 217 | +conditionals: |
| 218 | + |
| 219 | +```c |
| 220 | +/* BAD */ |
| 221 | +#if MODULE_GNRC_IPV6_EXT_FRAG_STATS |
| 222 | + _stats.fragments++; |
| 223 | + _stats.datagrams++; |
| 224 | +#endif /* MODULE_GNRC_IPV6_EXT_FRAG_STATS */ |
| 225 | +``` |
| 226 | + |
| 227 | +```c |
| 228 | +/* GOOD */ |
| 229 | +if (IS_USED(MODULE_GNRC_IPV6_EXT_FRAG_STATS)) { |
| 230 | + _stats.fragments++; |
| 231 | + _stats.datagrams++; |
| 232 | +} |
| 233 | +``` |
| 234 | + |
| 235 | +That way tooling such as language servers and static code analysers will still |
| 236 | +see the code and perform their checks on it. |
| 237 | + |
| 238 | +If preprocessor conditionals are needed, use `#ifdef MODULE_FOO` or |
| 239 | +`#if MODULE_FOO` instead of `#if IS_USED(MODULE_FOO)` |
| 240 | + |
| 241 | +The general rule is to reduce preprocessor statements as much as possible. |
| 242 | +Instead of guarding individual code sections, add a stub or use early returns: |
| 243 | + |
| 244 | +```c |
| 245 | +/* BAD */ |
| 246 | +#ifdef MODULE_FOO |
| 247 | +# include "foo.h" |
| 248 | +#endif /* MODULE_FOO */ |
| 249 | + |
| 250 | +#ifdef MODULE_FOO |
| 251 | +static void _do_foo(void) { |
| 252 | + // do foo |
| 253 | + ... |
| 254 | +} |
| 255 | +#endif /* MODULE_FOO */ |
| 256 | + |
| 257 | +void bar(my_type t) { |
| 258 | + switch(t) |
| 259 | +#ifdef MODULE_FOO |
| 260 | + case MY_TYPE_FOO: |
| 261 | + _do_foo(); |
| 262 | +#endif /* MODULE_FOO */ |
| 263 | + ... |
| 264 | +} |
| 265 | +``` |
| 266 | +
|
| 267 | +```c |
| 268 | +/* GOOD: Stubs */ |
| 269 | +#include "foo.h" |
| 270 | +
|
| 271 | +#ifdef MODULE_FOO |
| 272 | +static void _do_foo(void) { |
| 273 | + // do foo |
| 274 | + ... |
| 275 | +} |
| 276 | +#else |
| 277 | +/* No-op stub */ |
| 278 | +void _do_foo(void) { |
| 279 | + return; |
| 280 | +} |
| 281 | +#endif /* MODULE_FOO */ |
| 282 | +
|
| 283 | +void bar(my_type t) { |
| 284 | + switch(t) |
| 285 | + case MY_TYPE_FOO: |
| 286 | + _do_foo(); |
| 287 | + ... |
| 288 | +} |
| 289 | +``` |
| 290 | + |
| 291 | +```c |
| 292 | +/* GOOD: Early Returns */ |
| 293 | +#include "foo.h" |
| 294 | + |
| 295 | +static void _do_foo(void) { |
| 296 | + if (!IS_USED(MODULE_FOO)) { |
| 297 | + return; |
| 298 | + } |
| 299 | + // do foo |
| 300 | + ... |
| 301 | +} |
| 302 | + |
| 303 | +void bar(my_type t) { |
| 304 | + switch(t) |
| 305 | + case MY_TYPE_FOO: |
| 306 | + _do_foo(); |
| 307 | + break; |
| 308 | + ... |
| 309 | +} |
| 310 | +``` |
| 311 | +
|
| 312 | +The compiler will eliminate dead branches. |
| 313 | +
|
212 | 314 | ## Indentation of Preprocessor Directives |
213 | 315 |
|
214 | 316 | Add two spaces of indent *after* the `#` per level of indent. Increment the |
|
0 commit comments