| |
| - 8ch indent, no tabs |
| |
| - Variables and functions *must* be static, unless they have a |
| protoype, and are supposed to be exported. |
| |
| - structs in MixedCase, variables + functions in lower_case |
| |
| - The destructors always unregister the object from the next bigger |
| object, not the other way around |
| |
| - To minimize strict aliasing violations we prefer unions over casting |
| |
| - For robustness reasons destructors should be able to destruct |
| half-initialized objects, too |
| |
| - Error codes are returned as negative Exxx. i.e. return -EINVAL. There |
| are some exceptions: for constructors its is OK to return NULL on |
| OOM. For lookup functions NULL is fine too for "not found". |
| |
| Be strict with this. When you write a function that can fail due to |
| more than one cause, it *really* should have "int" as return value |
| for the error code. |
| |
| - Don't bother with error checking if writing to stdout/stderr worked. |
| |
| - Do not log errors from "library" code, only do so from "main |
| program" code. |
| |
| - Always check OOM. There's no excuse. In program code you can use |
| "log_oom()" for then printing a short message. |
| |
| - Do not issue NSS requests (that includes user name and host name |
| lookups) from the main daemon as this might trigger deadlocks when |
| those lookups involve synchronously talking to services that we |
| would need to start up |
| |
| - Don't synchronously talk to any other service, due to risk of |
| deadlocks |
| |
| - Avoid fixed sized string buffers, unless you really know the maximum |
| size and that maximum size is small. They are a source of errors, |
| since they result in strings to be truncated. Often it is nicer to |
| use dynamic memory, or alloca(). If you do allocate fixed size |
| strings on the stack, then it's probably only OK if you either use a |
| maximum size such as LINE_MAX, or count in detail the maximum size a |
| string can have. Or in other words, if you use "char buf[256]" then |
| you are likely doing something wrong! |
| |
| - Stay uniform. For example, always use "usec_t" for time |
| values. Don't usec mix msec, and usec and whatnot. |
| |
| - Make use of _cleanup_free_ and friends. It makes your code much |
| nicer to read! |
| |
| - Be exceptionally careful when formatting and parsing floating point |
| numbers. Their syntax is locale dependent (i.e. "5.000" in en_US is |
| generally understood as 5, while on de_DE as 5000.). |
| |
| - Try to use this: |
| |
| void foo() { |
| } |
| |
| instead of this: |
| |
| void foo() |
| { |
| } |
| |
| But it's OK if you don't. |
| |
| - Don't write "foo ()", write "foo()". |
| |
| - Please use streq() and strneq() instead of strcmp(), strncmp() where applicable. |
| |
| - Please do not allocate variables on the stack in the middle of code, |
| even if C99 allows it. Wrong: |
| |
| { |
| a = 5; |
| int b; |
| b = a; |
| } |
| |
| Right: |
| |
| { |
| int b; |
| a = 5; |
| b = a; |
| } |
| |
| - Unless you allocate an array, "double" is always the better choice |
| than "float". Processors speak "double" natively anyway, so this is |
| no speed benefit, and on calls like printf() "float"s get upgraded |
| to "double"s anyway, so there is no point. |
| |
| - Don't invoke functions when you allocate variables on the stack. Wrong: |
| |
| { |
| int a = foobar(); |
| uint64_t x = 7; |
| } |
| |
| Right: |
| |
| { |
| 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. |
| |
| - Think about the types you use. If a value cannot sensibly be |
| negative don't use "int", but use "unsigned". |
| |
| - Don't use types like "short". They *never* make sense. Use ints, |
| longs, long longs, all in unsigned+signed fashion, and the fixed |
| size types uint32_t and so on, but nothing else. |