C99: Suggestions for style(9)

Julian Elischer julian at elischer.org
Sat May 2 17:55:43 UTC 2009


Christoph Mallon wrote:
> Julian Elischer schrieb:
>> David Malone wrote:
>>>>> -Do not put declarations
>>>>> -inside blocks unless the routine is unusually complicated.
>>>>> +Prefer declaring loop iterators in the for-statement to limit 
>>>>> their scope.
>>>
>>> I usually don't like this style - I like being able to review the
>>> variables used in a function at the top.
>>
>> me too
>> though I've softenned a bit regarding puting variables in blocks,
>> I do NOT want to see variable declaration "not at the top of a block".
> 
> I find this kind of strange, because this in-beetwen makes least sense 
> to me: Neither are all declarations grouped together nor are 
> declarations nicely connected to their initialisation and their scope is 
> minimal.

I only have to look just after the enclosing "{"

I actually prefer to see them all at the top
but as I said I have seen cases where having them elsewhere makes sense.

> 
>>>>> -When declaring variables in functions declare them sorted by size,
>>>>> -then in alphabetical order; multiple ones per line are okay.
>>>>> +When declaring variables in functions declare them sorted in 
>>>>> alphabetical order;
>>>>> +prefer one declaration per line, especially when pointer 
>>>>> declarators or +initializations are involved.
>>>
>>> The change to prefer one declaration per line seems like an unnecessary,
>>> except to better accomodate the declare-at-initialisation below.
>>
>> the 'size' bit used to be to save space.. all the chars
>> would be grouped together, etc.
> 
> Today's compilers plain do not care in which order you declare 

I said "used to"

> variables. Sorting them in a beneficial way for space efficiency is 
> better left to them (and it is a rather trivial thing to do). Also you 
> cannot control if more spill slots have to be inserted or some values do 
> not live in memory at all, so only the compiler can determine, which 
> order is best.
> But a compiler can do more: It could coalesce the space of variables 
> with disjoint life ranges. But this is much harder, because you have to 
> properly determine the life ranges. Finding an arbitrary overestimation 
> is easy, but the fun starts when looking at called functions, which get 
> passed addresses of local variables. Also finding an optimal coalescence 
> for known life ranges is NP-complete in the general case. But that's 
> another story. (:

re-using space or having block-local variables means that when you
are in the debugger, you can not look at the final value that
a variable had when you left (unexpectedly) the block.  This can
be a pain in the neck. (but only a debugging feature)

> 
>>>>> +Prefer initializing variables right at their declaration.
>>>
>>
>> I have gone the other way on this.  Unless 'const' is being used I 
>> find I prefer to see them separately initialized.
> 
> So you like hunting in multiple places instead of having both type and 
> value conveniently in one place?

Actually.. yes
unconditional initialization is right at the top, AFTER the blank 
line. Conditional initialization must of course come after the 
condition, and can not be in the same line as the declaration anyhow.

> 
>>>>> +This makes it easier for a reader to identify the where the value 
>>>>> of a variable
>>>>> +originates.
>>
>> yeah.. at the top of the function..
> 
> Currently only the *declaration* is at the top of the function. This 
> bears absolutely no relation to where the *value* originates.

As I said.. unconditional values originate just after that, at the 
top.  :-)


> 
>>>>> +Do not reuse the same variable in a different context, delare a 
>>>>> new variable.
>>>
>>> I buy this largely - though it should be applied with common sense
>>> as usual.
>>
>> hmm. I think an exception might be made for our old friends i,j,k
> 
> Especially they should be declared right where they are needed. C99 even 
> conveniently allows the iterator variable to be declared in the first 
> part of a for-loop: for (int i = 0; i != n; ++i) { ... }. By limiting 
> their scope, this prevents accidently re-using stale values in a 
> different place or other mistakes like the following:
>     int i, j;
>     for (i = 0;; ++i) {
>         for (i = 0;; ++i) {
>             /* oops, but compiler is happy */
>         }
>     }
>     for (j = 0;; ++j) {
>         /* more */
>     }
> vs.
>     for (int i = 0;; ++i) {
>         for (int i = 0;; ++i) {
>             /* warning about shadowed variable */
>         }
>     }
>     for (int j = 0;; ++j) {
>         /* more */
>     }

while tempting, I can't see that hapenning..

it stops teh following:


for (;;) {
   blah
   if (foo)
	break;
}
if (i == end_condition) {
   then we didn't break out;
}


> 
>> everyone knows them and what they are doing.. otherwise,yes this makes 
>> sense.
>>
>>>
>>>>> -Values in
>>>>> -.Ic return
>>>>> -statements should be enclosed in parentheses.
>>>>> -.Pp
>>>
>>> This is another change that isn't worth making - style(9) has had
>>> this rule for years and changing it because you don't think it adds
>>> anything isn't a good reason.
>>>
>>
>> amen
> 
> This is no church. I presented reasons, I do not want beliefs in return. 
> Also stating that it should not be changed because it was always this 
> way is a very slippery slope.
> 
>>>>> -Use ANSI function declarations unless you explicitly need K&R 
>>>>> compatibility.
>>>>> +Use ANSI function declarations.
>>>
>>
>> Everyone shuld be doing that already.
>> In new code, and in old code that they touch.
> 
> So, is this pro or contra removing the K&R-clause?

K&R code should be changed as part of related changes if possible.
A sweep to change a whole file is probably also ok.
changing them one at a time is probably not ok.

> 
>     Christoph



More information about the freebsd-hackers mailing list