[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250509203430.3448-7-adobriyan@gmail.com>
Date: Fri, 9 May 2025 23:34:28 +0300
From: Alexey Dobriyan <adobriyan@...il.com>
To: corbet@....net
Cc: workflows@...r.kernel.org,
linux-kernel@...r.kernel.org,
Alexey Dobriyan <adobriyan@...il.com>
Subject: [PATCH 7/9] CodingStyle: new variable declaration placement rule
Linux finally compiles without -Wdeclaration-after-statement allowing
to declare variables anywhere in the code.
The rule is that variable is declared as late as possible:
1) it is possible to typo a variable and use by mistake between
declaration and first legitimate use.
Declaring variable later decreases this risk.
2) it is possible to typo variable between last legitimate use and
the end of the scope.
Declaring variable in the innermost scope decreases this risk.
3) declaring ALAP (as late as possible) often allows to merge declaration
and assignment into declaration with initializer. This saves LOC
without readability loss.
4) declaring ALAP allows to use "const" on the variable if necessary.
Linux doesn't use "const" much outside of "const T*" but with
split declaration/assignment it is not possible at all.
4) declaring lower naturally breaks some misguided rules (I'm being
polite here) about declarations: there is a rule saying that
declaration block in the beginning of the scope must be sorted
by length forming trapezoid-like shape
XXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXX
XXXXXXXXXXX
XXXXXXXXX
int rv;
so the code looks nicer (allegedly). This is misguided (still polite)
because code is formatted not for of objectively good characteristics
(bug risk, codegen quality, easy of maintainance) but for subjective
qualities like being aesthetically pleasing to look at.
5) K&R rule about declaring variables in the beginning of the scope is
pointless restriction. It is very obvious after programming something
other than C. All popular programming languages either never had K&R
rule or discarded it at some point implying that even if it was
useful (it wasn't), it was so marginally useful that everyone thought
it is not worth it.
This patch makes 100% of the code non-compliant, but, oh well...
Signed-off-by: Alexey Dobriyan <adobriyan@...il.com>
---
Documentation/process/coding-style.rst | 72 ++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst
index f8d5151eb0d2..e17de69845ff 100644
--- a/Documentation/process/coding-style.rst
+++ b/Documentation/process/coding-style.rst
@@ -95,6 +95,78 @@ used for indentation, and the above example is deliberately broken.
Get a decent editor and don't leave whitespace at the end of lines.
+Variable declarations
+---------------------
+
+Each variable is declared in the innermost scope possible
+where ``for`` initialization clause counts as a scope as well.
+
+Inside specific scope each variable is declared as late as possible as if
+declarations have "mass" and "fall down":
+
+.. code-block:: c
+
+ int f(void *priv)
+ {
+ struct xxx_obj *obj = to_xxx_obj(priv);
+
+ rcu_read_lock();
+ int s_xxx = 0;
+ for (int i = 0; i < n_xxx; i++) {
+ s_xxx += obj->xxx[i];
+ }
+ rcu_read_unlock();
+
+ unsigned long flags;
+ spin_lock_irqsave(&obj->lock, &flags);
+ int rv = obj_make(obj, s_xxx);
+ spin_unlock_irqrestore(&obj->lock, &flags);
+ return rv;
+ }
+
+
+These rules minimise a) the risk of variable misuse between declaration and
+first legitimate use, b) allow to transform declaration and first assignment
+into declaration with initializer saving LOC on average without readability
+loss and c) allow to use ``const`` if necessary:
+
+.. code-block:: c
+
+ T a;
+ T b;
+
+ a = g();/* bug, should be "b = " */
+
+ a = f();
+
+ vs
+
+ T b;
+ a = g(); /* compile error */
+ [const] T a = f(); /* OK */
+
+Each declaration is put on its own line:
+
+.. code-block:: c
+
+ T a = ...;
+ T tmp;
+
+C allows to declare multiple variables in the same statement but it is
+a misfeature. It leads to confusion if pointers are involved, even more
+confusion and long lines with initializers (likely going above character
+limit) and avoidable changes in patches.
+
+Very long declarations are split after the ``=`` character:
+
+.. code-block:: c
+
+ struct xxx_obj *obj =
+ xxx_obj_alloc(Long, list, of, arguments);
+
+Most of the time both lines fit just fine into the character limit afterwards.
+
+
Breaking long lines and strings
-------------------------------
--
2.49.0
Powered by blists - more mailing lists