Index
Home
About
Blog
Date: Wed, 30 Aug 2000 10:04:12 -0700 (PDT)
From: Linus Torvalds <torvalds@transmeta.com>
Subject: Re: [PATCH] af_rose.c: s/suser/capable/ + micro cleanups
Newsgroups: fa.linux.kernel
On Wed, 30 Aug 2000, Rogier Wolff wrote:
>
> > source code smaller and more easier to read (yes, this is debatable,
> > I think it becomes more clean, other think otherwise, I'm just
> > following what Linus said he prefer).
>
> The kernel is a multi-million-lines-of-code piece of software.
> Software maintenance cost is found to correlate strongly with the
> number of lines-of-code.
>
> So, I would prefer the shorter version.
I disagree.
Number of lines is irrelevant.
The _complexity_ of lines counts.
And ?: is a complex construct, that is not always visually very easy to
parse because of the "non-local" behaviour.
That is not saying that I think you shouldn't use ?: at all. It's a
wonderful construct in many ways, and I use it all the time myself. But I
actually prefer
if (complex_test)
return complex_expression1;
return complex_expression2;
over
return (complex_test) ? complex_expression1 : complex_expression2;
because by the time you have a complex ?: thing it's just not very
readable any more.
Basically, dense lines are bad. And ?: can make for code that ends up "too
dense".
More specific example: I think
return copy_to_user(dst, src, size) ? -EFAULT : 0;
is fine and quite readable. Fits on a simple line.
However, it's getting iffy when it becomes something like
return copy_to_user(buf, page_address(page) + offset, size) ? -EFAULT: 0;
for example. The "return" is so far removed from the actual return values,
that it takes some parsing (maybe you don't even see everything on an
80-column screen, or even worse, you split up one expression over several
lines..
(Basically, I don't like multi-line expressions. Avoid stuff like
x = ...
+ ...
- ...;
unless it is _really_ simple. Similarly, some people split up their
"for ()" or "while ()" statement things - which usually is just a sign of
the loop baing badly designed in the first place. Multi-line expressions
are sometimes unavoidable, but even then it's better to try to simplify
them as much as possible. You can do it by many means
- make an inline function that has a descriptive name. It's still
complex, but now the complexity is _described_, and not mixed in with
potentially other complex actions.
- Use logical grouping. This is sometimes required especially in "if()"
statements with multiple parts (ie "if ((x || y) && !z)" can easily
become long - but you might consider just the above inline function or
#define thing).
- Use multiple statements. I personally find it much more readable to
have
if (PageTestandClearReferenced(page))
goto dispose_continue;
if (!page->buffers && page_count(page) > 1)
goto dispose_continue;
if (TryLockPage(page))
goto dispose_continue;
rather than the equivalent
if (PageTestandClearReferenced(page) ||
(!page->buffers && page_count(page) > 1) ||
TryLockPage(page))
goto dispose_continue;
regardless of any grouping issues.
Basically, lines-of-code is a completely bogus metric for _anything_.
Including maintainability.
> If it takes you a few seconds to look this over, that's fine. Even it
> the one "complicated" line take twice as long (per line) as the
> original 4 lines, then it's a win.
I disagree violently.
Linus
Index
Home
About
Blog