]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - docs/CODING_STYLE.md
tree-wide: use "hostname" spelling everywhere
[thirdparty/systemd.git] / docs / CODING_STYLE.md
index 9b2fd5cc842b9f2ad0212c82b2fa470adfd42a06..12a0c993fc99f37eb224458983d4adc48a25f078 100644 (file)
@@ -1,5 +1,7 @@
 ---
 title: Coding Style
+category: Contributing
+layout: default
 ---
 
 # Coding Style
@@ -55,53 +57,49 @@ title: Coding Style
 
 - Do not write `foo ()`, write `foo()`.
 
-## Other
+## Code Organization and Semantics
 
 - Please name structures in `PascalCase` (with exceptions, such as public API
   structs), variables and functions in `snake_case`.
 
-- Avoid static variables, except for caches and very few other
-  cases. Think about thread-safety! While most of our code is never
-  used in threaded environments, at least the library code should make
-  sure it works correctly in them. Instead of doing a lot of locking
-  for that, we tend to prefer using TLS to do per-thread caching (which
-  only works for small, fixed-size cache objects), or we disable
-  caching for any thread that is not the main thread. Use
-  `is_main_thread()` to detect whether the calling thread is the main
-  thread.
+- Avoid static variables, except for caches and very few other cases. Think
+  about thread-safety! While most of our code is never used in threaded
+  environments, at least the library code should make sure it works correctly
+  in them. Instead of doing a lot of locking for that, we tend to prefer using
+  TLS to do per-thread caching (which only works for small, fixed-size cache
+  objects), or we disable caching for any thread that is not the main
+  thread. Use `is_main_thread()` to detect whether the calling thread is the
+  main thread.
 
 - Do not write functions that clobber call-by-reference variables on
-  failure. Use temporary variables for these cases and change the
-  passed in variables only on success.
+  failure. Use temporary variables for these cases and change the passed in
+  variables only on success.
 
 - The order in which header files are included doesn't matter too
-  much. systemd-internal headers must not rely on an include order, so
-  it is safe to include them in any order possible.
-  However, to not clutter global includes, and to make sure internal
-  definitions will not affect global headers, please always include the
-  headers of external components first (these are all headers enclosed
-  in <>), followed by our own exported headers (usually everything
-  that's prefixed by `sd-`), and then followed by internal headers.
-  Furthermore, in all three groups, order all includes alphabetically
+  much. systemd-internal headers must not rely on an include order, so it is
+  safe to include them in any order possible.  However, to not clutter global
+  includes, and to make sure internal definitions will not affect global
+  headers, please always include the headers of external components first
+  (these are all headers enclosed in <>), followed by our own exported headers
+  (usually everything that's prefixed by `sd-`), and then followed by internal
+  headers.  Furthermore, in all three groups, order all includes alphabetically
   so duplicate includes can easily be detected.
 
-- 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
-  exported. Especially in library-like code it is important to avoid
-  global variables. Why are global variables bad? They usually hinder
-  generic reusability of code (since they break in threaded programs,
-  and usually would require locking there), and as the code using them
-  has side-effects make programs non-transparent. That said, there are
-  many cases where they explicitly make a lot of sense, and are OK to
-  use. For example, the log level and target in `log.c` is stored in a
-  global variable, and that's OK and probably expected by most. Also
-  in many cases we cache data in global variables. If you add more
-  caches like this, please be careful however, and think about
-  threading. Only use static variables if you are sure that
-  thread-safety doesn't matter in your case. Alternatively, consider
-  using TLS, which is pretty easy to use with gcc's `thread_local`
-  concept. It's also OK to store data that is inherently global in
-  global variables, for example data parsed from command lines, see
+- 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 exported. Especially in
+  library-like code it is important to avoid global variables. Why are global
+  variables bad? They usually hinder generic reusability of code (since they
+  break in threaded programs, and usually would require locking there), and as
+  the code using them has side-effects make programs non-transparent. That
+  said, there are many cases where they explicitly make a lot of sense, and are
+  OK to use. For example, the log level and target in `log.c` is stored in a
+  global variable, and that's OK and probably expected by most. Also in many
+  cases we cache data in global variables. If you add more caches like this,
+  please be careful however, and think about threading. Only use static
+  variables if you are sure that thread-safety doesn't matter in your
+  case. Alternatively, consider using TLS, which is pretty easy to use with
+  gcc's `thread_local` concept. It's also OK to store data that is inherently
+  global in global variables, for example data parsed from command lines, see
   below.
 
 - You might wonder what kind of common code belongs in `src/shared/` and what
@@ -205,6 +203,19 @@ title: Coding Style
   array. In that case use STRLEN, which evaluates to a static constant and
   doesn't force the compiler to create a VLA.
 
+- Please use C's downgrade-to-bool feature only for expressions that are
+  actually booleans (or "boolean-like"), and not for variables that are really
+  numeric. Specifically, if you have an `int b` and it's only used in a boolean
+  sense, by all means check its state with `if (b) …` — but if `b` can actually
+  have more than two semantic values, and you want to compare for non-zero,
+  then please write that explicitly with `if (b != 0) …`. This helps readability
+  as the value range and semantical behaviour is directly clear from the
+  condition check. As a special addition: when dealing with pointers which you
+  want to check for non-NULL-ness, you may also use downgrade-to-bool feature.
+
+- Please do not use yoda comparisons, i.e. please prefer the more readable `if
+  (a == 7)` over the less readable `if (7 == a)`.
+
 ## Destructors
 
 - The destructors always deregister the object from the next bigger object, not
@@ -227,7 +238,7 @@ title: Coding Style
   p = foobar_unref(p);
   ```
 
-  which will always work regardless if `p` is initialized or not,x and
+  which will always work regardless if `p` is initialized or not, and
   guarantees that `p` is `NULL` afterwards, all in just one line.
 
 ## Error Handling
@@ -413,7 +424,7 @@ title: Coding Style
 
 ## Deadlocks
 
-- Do not issue NSS requests (that includes user name and host name lookups)
+- Do not issue NSS requests (that includes user name and hostname lookups)
   from PID 1 as this might trigger deadlocks when those lookups involve
   synchronously talking to services that we would need to start up.
 
@@ -532,7 +543,7 @@ title: Coding Style
   time you need that please immediately undefine `basename()`, and add a
   comment about it, so that no code ever ends up using the POSIX version!
 
-# Committing to git
+## Committing to git
 
 - Commit message subject lines should be prefixed with an appropriate component
   name of some kind. For example "journal: ", "nspawn: " and so on.