Intro ===== I'm not a nazi about this (at least *I* don't think I am), but it's important for a program to have a consistent style throughout. These rules aren't cast in stone, but if you don't have a *good* reason to deviate, then don't. Otherwise, I will bitchslap you. After much deliberation (really, a *lot*), I've decided on a modified version of k&r style. If you use Emacs, just use k&r as your c-mode when hacking on Specimen. Braces ====== I used to follow the strict k&r layout, but after too many hours wasted furrowing my brow trying to focus on something like... if (p->play_mode & PATCH_PLAY_LOOP) { if (p->play_mode & PATCH_PLAY_PINGPONG) { if ((v->dir > 0) && (v->posi > p->loop_stop)) { v->posi = p->loop_stop; v->dir = -1; } else if ((v->dir < 0) && (v->posi < p->loop_start)) { v->posi = p->loop_start; v->dir = 1; } } else { if ((v->dir > 0) && (v->posi > p->loop_stop)) { v->posi = p->loop_start; } else if ((v->dir < 0) && (v->posi < p->loop_start)) { v->posi = p->loop_stop; } } } ...I decided that my A.D.H.D. ass was due for a change. The rule is, all braces have one line to themselves. Observe the difference in readability: if (p->play_mode & PATCH_PLAY_LOOP) { if (p->play_mode & PATCH_PLAY_PINGPONG) { if ((v->dir > 0) && (v->posi > p->loop_stop)) { v->posi = p->loop_stop; v->dir = -1; } else if ((v->dir < 0) && (v->posi < p->loop_start)) { v->posi = p->loop_start; v->dir = 1; } } else { if ((v->dir > 0) && (v->posi > p->loop_stop)) { v->posi = p->loop_start; } else if ((v->dir < 0) && (v->posi < p->loop_start)) { v->posi = p->loop_stop; } } } If this style of formatting costs you too much "screen real-estate," I doubt your system is in any shape to be running Specimen in the first place. Naming ====== Types should be written in StudlyCaps, and functions should be separated_with_underscores(). Variables which need some kind of multiword distinction should also take the underscore approach. I like this method because it makes the difference between types and functions eminently clear, as well as being a good metaphor for the singularity of types (they're just a thing) and the plurality of functions (they're a collection of actions). The first rule of name length is that length should be directly proportional to scope level. A variable that is local only to a particular function doesn't need a big name. On the other hand a function that will be used throughout the program should have a somewhat lengthier and more descriptive name. The second rule of name length is that length should be inversely proportional to frequency of use. If you're going to be using a variable a whole lot, you'll be well served to keep that name as short as is reasonable (not uncommonly down to one letter for function local variables). If you're going to be using a variable infrequently, it's name should be more descriptive so that you know what it is being used for when you go back to your code a week later. Functions ========= Global functions should follow this naming convention: namespace_operation_qualifier(args); Functions should be focused and to the point. gcc has an inline keyword, so don't hesitate to break up a function into smaller pieces if it's starting to get unwieldy. A good indicator is if it gets to be more than 150 lines, or has more than 10 local variables. Another indicator is if the indentation level is more than 3, although it is sometimes desirable to go for a 4th level of indentation rather than split off into another function. If your function is conceptually quite simple, than it's ok to break the above rules. However, if a retard like me won't be able to figure out what's going on, you should stay well within the limits. Oh, and if a function doesn't take any parameters, declare it as foo(void). Otherwise, compilers will assume your using oldskool function prototype parameter declarations (i.e., none), and that ain't good. Pointers ======== When declaring pointer types, this sytnax... int* foo; ...is preferred over this... int *foo; ...and this... int * foo; The reason is that the first very clearly says "integer pointer" by smacking the pointer right up there with the type. And anyway, the asterik is just another type qualifier, and it ought to be with all the other type qualifiers. You never see anybody write static const int foo; The reason? It's stupid. Don't be stupid. Commenting ========== From the Linux Kernel Coding Style guidelines: "Comments are good, but there is also a danger of over-commenting. Never try to explain how your code works in a comment: it's much better to write the code so that the working is obvious, and it's a waste of time to explain badly written code." "Generally, you want your comments to tell what your code does, not how. Also, try to avoid putting comments inside a function body: if the function is so complex that you need to separately comment parts of it, you should probably go back to chapter 4 for a while. You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess. Instead, put the comments at the head of the function, telling people what it does, and possibly why it does it." It is vastly more important to comment data structures than it is functions. I cannot stress this enough. When the data structures are well understood, everything else falls into place. However, a well understood function that operates on mystery data is still unfathomable in a practical sense. You have to really dedicate yourself if you want to over-comment a data structure, and you'll probably fail anyway. Functions, on the other hand, can be over-commented almost instantly. When it comes to commenting, make sure your data structures get *lots* of love, but don't sweat your functions so much. In those rare circumstances where an incredible subtlety is at play, or an imperfection which cannot be solved at the moment needs a note to remind you to fix it, beefy function comments may be merited (but exercise prodigious discretion). On the whole, however, everything you learned in Comp Sci, if anything at all, is totally wrong and should be ignored/forgotten ASAP. But I Want To Do It My Way ========================== Fine, be a bitch. Just run the following indent command when you're done, and you'll probably get acceptable results. indent -kr -bad -bl -bls -bli0 -bs -nce Misc ==== Use spacing to your advantage. The human mind works really well with a table based layout. The following: int function_way_too_freakin_long(); /* blistered earth rules */ int function_one(int foo); /* metallica sucks */ int function_twenty(int bar); /* was anyone honestly surprised about halford? */ Is much more readable when laid out thusly: int function_way_too_freakin_long (); /* blistered earth rules */ int function_one (int foo); /* metallica sucks */ int function_twenty (int bar); /* was anyone honestly surprised about halford? */ This kind of thing is typically seen in header files, but don't be afraid to use the same technique to clean up intricate code that tends to induce migraines in whomsoever attempts to read it. At the time of this writing [2004-06-06], lots of Specimen blatantly disregards the above rules. So sue me, I was (am) just starting out. I'm working on fixing that. Hopefully, by the time anybody reads this doc, this clause will no longer be relevant.