diff --git a/CODING_CONVENTIONS.md b/CODING_CONVENTIONS.md index d6d58b4a5d..bf3c89bdd2 100644 --- a/CODING_CONVENTIONS.md +++ b/CODING_CONVENTIONS.md @@ -3,7 +3,7 @@ ## General * Code shall be [C11](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) - compliant. + compliant, with a list of exceptions detailed below. * Avoid dynamic memory allocation (malloc/free, new, etc.)! It will break real-time guarantees, increase code complexity, and make it more likely to use more memory than available. @@ -43,6 +43,39 @@ * You can use [uncrustify](http://uncrustify.sourceforge.net/) with the provided option files: https://github.com/RIOT-OS/RIOT/blob/master/uncrustify-riot.cfg +## Standard Compliance + +Using extensions to the C standard in general decreases portability and +maintainability: The former because porting RIOT to platforms for which limited +compiler options are available becomes more difficult when compiler-specific +extensions are used. The latter because extensions are often not as clearly +defined as standard C, not as well known within the C development community, +and have fewer resources to look up. + +There are a number of cases in which using extensions cannot be avoided, or +would not be maintainable. For these cases, an exception can be made. A list +of recognised exceptions where we can (or even must) rely on extensions include: + +- Use of `__attribute__((packed))` is allowed for serialization and + de-serialization and only there. Ideally, it should not be used in public + APIs and types. +- Code specific to MCU families may use extensions commonly used in this domain, + such as inline assembly (e.g. as needed for context swapping), special + function attributes (e.g. as needed for IRQ vector entries on some MCUs), + etc. Code should still prefer standard compliance when there is no significant + downside to it compared to using the extension. +- `#include_next` may be used when system headers need to be extended. +- Function attributes for which a wrapper exists in `compiler_hints.h` may be + used using that wrapper. These wrappers either unlock additional optimization + (such as `NORETURN` or `PURE`) or influence warnings (such as `MAYBE_UNUSED`) + produced by the compiler and can simply be replaced by an empty token for + compilers that do not support them. +- `__attribute__((used))`, `__attribute__((section("...")))`, + `__attribute__((weak))`, and `__attribute__((alias("...")))` + can be used where applicable. Unlike the wrappers in `compiler_hints.h`, we + actually require toolchain support for them (an empty-token implementation + will not generate correct binaries). + ## Types * Be careful with platform dependent type sizes like `int` or `long`. Use data