Plan 9 Coding Conventions for C
plan9.bell-labs.com
plan9.bell-labs.com
don't use // comments; some old Plan 9 code does, but we're converting it as we touch it. We do sometimes use // to comment–out a few lines of code.
Doesn't make sense with any decent editor, you ought to comment via macros.
no braces around single–line blocks (e.g., if, for, and while bodies)
I kind of like enforcing the opposite (always use braces).
Otherwise you end up with things like:
if (statement)
one; two;Not sure I follow you on the one; two; example. Why would you have two statements per line in the first place? (You do realize that the "two;" isn't in the if block, right?)
if (statement) one;
And developper two added
if (statement) one; two;
too quickly
If you had a coding convention of always using braces in if statements, you might be insulated from this particular symptom or instance of the problem, but you still have the underlying problem that people are doing things without thinking.
You can solve this problem?
People are fallible, mistakes get made.
The actual argument has been made in sibling comments: braces are verbose, and the mistake we speak of is exceedingly rare in practice. For simple one-liners, the verbosity costs more than the lack of safety net.
A lint tool checking for suspicious indentation would be a better use of labour.
These types of conventions -- no curlies around simple blocks -- aren't too bad if a) your devs are adequately seasoned, and b) your devs believe in whitespace.
For instance, this isn't really so bad:
if (foo)
foo();
else
bar();
Hell, that's clean!But it's stuff like this that causes issues:
if(foo)foo();
else bar();
Sometimes I'm lucky and find this: if (foo)
foo();
else {
bar();
baz();
}
The best is abominations like this though; first, the sane formatting: if (foo)
while (i++ < x)
foo(i);
else
bar();
Or, as I have found it: if(foo)while(i++<x)foo(i);
else bar();
Seriously, that's enough for me to revoke commit privs. if(flag)
set_other_flag=1;
call_function();
(both lines necessary)Anyway, it didn't take long to narrow it down to that bit of code but it took a few more minutes to figure out why the function was always getting called. I couldn't work out what was going on until I looked at the disassembly and was forced to reassess my opinion of what code was actually being compiled. Too much python in my diet, perhaps.
I remember being surprised at the time that it had taken so long for this to happen, and I made a mental note to keep an eye out for more occurrences. That was summer 2006, and I haven't seen it happen since.
#define one a;b;
if (statement) one;
if (statement)
// one;
two; if(a)
if(b)
x;
else
y;
This doesn't do what the indentation implies. (http://en.wikipedia.org/wiki/Dangling_else)Walter Bright (creator of D, etc.) has an article where he discusses his interesting choice to make that grammar form illegal in D. He mentions that after doing this he found a bug in D's runtime library. http://www.drdobbs.com/cpp/dangling-else-yet-again/231602010
We generally don't even like have non-curlied one-liners in our conditionals.
printf("Legit code\n");
#if 0
/* bunch of code to comment out */
printf("Commented code\n");
#endifThey are current rules also. The rules are largely the same as BSD rules, and go rules. Just because they are old, doesn't mean the people who wrote them moved on to doing what the trendy javascript kids do.
https://github.com/tcltk/tcl/blob/master/generic/tclConfig.c
Although I think arguing for less uppercase/camelcase would not be entirely out of place. Still though, it's very nice to read.
[1] http://www.amazon.com/Practice-Programming-Addison-Wesley-Pr... [2] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sekti...
That sounds odd
Oh, finally.
Tabs for indentation levels, spaces for alignment. How hard can it be?
> no white space after the keywords if, for, while, etc.
Woh, my workplace enforces the exact opposite! The idea is that if, while, etc are not functions, therefore `if (x)` is unacceptable but `my_func(x)` is ok. I personally prefer `if(x)` though. int needfid[] = {
[Tversion] 0,
[Tflush] 0,
[Tauth] 0,
syntax means? Is this some Plan 9 extension, or is it just something I've never encountered?EDIT: I guess the value in the []'s is the array index to set the value of.
It's C99 (I also only saw it in C99 articles, never in production code). See http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits...
int needfid[] = {
[Tversion] = 0,
[Tflush] = 0,
It works for structs too: struct blah needfid = {
.version = 0,
.flush = 0, warning: use of GNU 'missing =' extension in designator
[-Wgnu-designator]http://plan9.bell-labs.com/sys/doc/compiler.html
It seems like it was contemporaneous with the proposed c90 extension and also supported the = except optionally. But it was definitely something in the plan 9 compiler rather than only a gcc thing.
Don't conventions 6, 7, 8, and 11 violate this?
"Ultimately, the goal is to write code that fits in with the other code around it and the system as a whole. If the file you are editing already deviates from these guidelines, do what it does. After you edit a file, a reader should not be able to tell just from coding style which parts you worked on."
This is a real boon to other people on your team.