CODING_STYLE: add section about C constructs use
This commit is contained in:
parent
3b75e079a8
commit
78e5b4d7ee
|
@ -55,53 +55,15 @@ title: Coding Style
|
||||||
|
|
||||||
- Do not write `foo ()`, write `foo()`.
|
- Do not write `foo ()`, write `foo()`.
|
||||||
|
|
||||||
- Preferably allocate local variables on the top of the block:
|
|
||||||
|
|
||||||
```c
|
|
||||||
{
|
|
||||||
int a, b;
|
|
||||||
|
|
||||||
a = 5;
|
|
||||||
b = a;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Other
|
## Other
|
||||||
|
|
||||||
- structs in `PascalCase` (with exceptions, such as public API structs),
|
- Please name structures in `PascalCase` (with exceptions, such as public API
|
||||||
variables and functions in `snake_case`.
|
structs), variables and functions in `snake_case`.
|
||||||
|
|
||||||
- To minimize strict aliasing violations, we prefer unions over casting.
|
|
||||||
|
|
||||||
- Be exceptionally careful when formatting and parsing floating point
|
- Be exceptionally careful when formatting and parsing floating point
|
||||||
numbers. Their syntax is locale dependent (i.e. `5.000` in en_US is
|
numbers. Their syntax is locale dependent (i.e. `5.000` in en_US is
|
||||||
generally understood as 5, while in de_DE as 5000.).
|
generally understood as 5, while in de_DE as 5000.).
|
||||||
|
|
||||||
- Do not mix function invocations with variable definitions in one
|
|
||||||
line. Wrong:
|
|
||||||
|
|
||||||
```c
|
|
||||||
{
|
|
||||||
int a = foobar();
|
|
||||||
uint64_t x = 7;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Right:
|
|
||||||
|
|
||||||
```c
|
|
||||||
{
|
|
||||||
int a;
|
|
||||||
uint64_t x = 7;
|
|
||||||
|
|
||||||
a = foobar();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- Use `goto` for cleaning up, and only use it for that. i.e. you may
|
|
||||||
only jump to the end of a function, and little else. Never jump
|
|
||||||
backwards!
|
|
||||||
|
|
||||||
- Avoid static variables, except for caches and very few other
|
- Avoid static variables, except for caches and very few other
|
||||||
cases. Think about thread-safety! While most of our code is never
|
cases. Think about thread-safety! While most of our code is never
|
||||||
used in threaded environments, at least the library code should make
|
used in threaded environments, at least the library code should make
|
||||||
|
@ -116,27 +78,6 @@ title: Coding Style
|
||||||
failure. Use temporary variables for these cases and change the
|
failure. Use temporary variables for these cases and change the
|
||||||
passed in variables only on success.
|
passed in variables only on success.
|
||||||
|
|
||||||
|
|
||||||
- Instead of using `memzero()`/`memset()` to initialize structs allocated
|
|
||||||
on the stack, please try to use c99 structure initializers. It's
|
|
||||||
short, prettier and actually even faster at execution. Hence:
|
|
||||||
|
|
||||||
```c
|
|
||||||
struct foobar t = {
|
|
||||||
.foo = 7,
|
|
||||||
.bar = "bazz",
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
instead of:
|
|
||||||
|
|
||||||
```c
|
|
||||||
struct foobar t;
|
|
||||||
zero(t);
|
|
||||||
t.foo = 7;
|
|
||||||
t.bar = "bazz";
|
|
||||||
```
|
|
||||||
|
|
||||||
- The order in which header files are included doesn't matter too
|
- The order in which header files are included doesn't matter too
|
||||||
much. systemd-internal headers must not rely on an include order, so
|
much. systemd-internal headers must not rely on an include order, so
|
||||||
it is safe to include them in any order possible.
|
it is safe to include them in any order possible.
|
||||||
|
@ -148,13 +89,6 @@ title: Coding Style
|
||||||
Furthermore, in all three groups, order all includes alphabetically
|
Furthermore, in all three groups, order all includes alphabetically
|
||||||
so duplicate includes can easily be detected.
|
so duplicate includes can easily be detected.
|
||||||
|
|
||||||
- To implement an endless loop, use `for (;;)` rather than `while (1)`.
|
|
||||||
The latter is a bit ugly anyway, since you probably really
|
|
||||||
meant `while (true)`. To avoid the discussion what the right
|
|
||||||
always-true expression for an infinite while loop is, our
|
|
||||||
recommendation is to simply write it without any such expression by
|
|
||||||
using `for (;;)`.
|
|
||||||
|
|
||||||
- Avoid leaving long-running child processes around, i.e. `fork()`s that
|
- Avoid leaving long-running child processes around, i.e. `fork()`s that
|
||||||
are not followed quickly by an `execv()` in the child. Resource
|
are not followed quickly by an `execv()` in the child. Resource
|
||||||
management is unclear in this case, and memory CoW will result in
|
management is unclear in this case, and memory CoW will result in
|
||||||
|
@ -165,12 +99,6 @@ title: Coding Style
|
||||||
something some time", or so is a lazy excuse. Always wait for the
|
something some time", or so is a lazy excuse. Always wait for the
|
||||||
proper event, instead of doing time-based poll loops.
|
proper event, instead of doing time-based poll loops.
|
||||||
|
|
||||||
- To determine the length of a constant string `"foo"`, don't bother with
|
|
||||||
`sizeof("foo")-1`, please use `strlen()` instead (both gcc and clang optimize
|
|
||||||
the call away for fixed strings). The only exception is when declaring an
|
|
||||||
array. In that case use STRLEN, which evaluates to a static constant and
|
|
||||||
doesn't force the compiler to create a VLA.
|
|
||||||
|
|
||||||
- Please avoid using global variables as much as you can. And if you
|
- Please avoid using global variables as much as you can. And if you
|
||||||
do use them make sure they are static at least, instead of
|
do use them make sure they are static at least, instead of
|
||||||
exported. Especially in library-like code it is important to avoid
|
exported. Especially in library-like code it is important to avoid
|
||||||
|
@ -238,6 +166,76 @@ title: Coding Style
|
||||||
expansion. When doing the reverse, make sure to escape `%` in specifier-style
|
expansion. When doing the reverse, make sure to escape `%` in specifier-style
|
||||||
first (i.e. `%` → `%%`), and then do C-style escaping where necessary.
|
first (i.e. `%` → `%%`), and then do C-style escaping where necessary.
|
||||||
|
|
||||||
|
## Using C Constructs
|
||||||
|
|
||||||
|
- Preferably allocate local variables on the top of the block:
|
||||||
|
|
||||||
|
```c
|
||||||
|
{
|
||||||
|
int a, b;
|
||||||
|
|
||||||
|
a = 5;
|
||||||
|
b = a;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Do not mix function invocations with variable definitions in one line. Wrong:
|
||||||
|
|
||||||
|
```c
|
||||||
|
{
|
||||||
|
int a = foobar();
|
||||||
|
uint64_t x = 7;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Right:
|
||||||
|
|
||||||
|
```c
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
uint64_t x = 7;
|
||||||
|
|
||||||
|
a = foobar();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Use `goto` for cleaning up, and only use it for that. i.e. you may only jump
|
||||||
|
to the end of a function, and little else. Never jump backwards!
|
||||||
|
|
||||||
|
- To minimize strict aliasing violations, we prefer unions over casting.
|
||||||
|
|
||||||
|
- Instead of using `memzero()`/`memset()` to initialize structs allocated on
|
||||||
|
the stack, please try to use c99 structure initializers. It's short, prettier
|
||||||
|
and actually even faster at execution. Hence:
|
||||||
|
|
||||||
|
```c
|
||||||
|
struct foobar t = {
|
||||||
|
.foo = 7,
|
||||||
|
.bar = "bazz",
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
instead of:
|
||||||
|
|
||||||
|
```c
|
||||||
|
struct foobar t;
|
||||||
|
zero(t);
|
||||||
|
t.foo = 7;
|
||||||
|
t.bar = "bazz";
|
||||||
|
```
|
||||||
|
|
||||||
|
- To implement an endless loop, use `for (;;)` rather than `while (1)`. The
|
||||||
|
latter is a bit ugly anyway, since you probably really meant `while
|
||||||
|
(true)`. To avoid the discussion what the right always-true expression for an
|
||||||
|
infinite while loop is, our recommendation is to simply write it without any
|
||||||
|
such expression by using `for (;;)`.
|
||||||
|
|
||||||
|
- To determine the length of a constant string `"foo"`, don't bother with
|
||||||
|
`sizeof("foo")-1`, please use `strlen()` instead (both gcc and clang optimize
|
||||||
|
the call away for fixed strings). The only exception is when declaring an
|
||||||
|
array. In that case use STRLEN, which evaluates to a static constant and
|
||||||
|
doesn't force the compiler to create a VLA.
|
||||||
|
|
||||||
## Destructors
|
## Destructors
|
||||||
|
|
||||||
- The destructors always deregister the object from the next bigger object, not
|
- The destructors always deregister the object from the next bigger object, not
|
||||||
|
|
Loading…
Reference in a new issue