Main / Cstyle
Recommended C Style Guide - Conclusions After A Decade of DevelopmentThis guide is based on the original K&R style from the inventors of C, Stroustrup's C++ additions (https://www.stroustrup.com/bs_faq2.html), adds in a couple of the preferences of the Linux kernel developers, picks up a few good points from Code Complete, and mixes in some other best practice advice. AestheticsUse parentheses around expressions as a general rule, for clarity and caution. For example if((x + 3) == y) When declaring a pointer, make the type clear with good asterisk placement, preferring what is sometimes called "C++ style" that is liked by C++ inventor Stroustrup: int* foo; /*OR*/ int * foo; /*NOT*/ int *foo; Follow K&R indentation, as this helps the eye when scanning code quickly and also limits empty lines: function() { } statement { } This is a good example of a less desirable style, as it can cause confusion: static void foo() { //code //code for (unsigned i=0; i<API_NUM_RECEIVERS; i++) rsp.putUInt32( 42 ); } CommentsAvoid using /*...*/ for single line comments. This interrupts an attempt to use them for blocks that contain these single line guys within. Double forward slash // is best for single line comments, while /* and */ are preferred for large chunks like file or function headers. DeclarationsLeave the parameter names out of a function forward declaration, so that the name does not need to change in two places in case of alteration: // preferred void foo(int); // extra work void foo(int bar); DimensionsTry to use 80 characters as the max line width as much as possible, but if splitting lines is too ugly to read, use 120 characters as a hard cap. Try to limit single function length to a one page view in the editor - anything longer than this needs some justification. Besides being easier to read/debug/maintain, and more likely re-usable, this will make it more likely the function could be pasted in its entirety into a PDF or Word doc without spilling over onto another page. NamingEnsure naming is consistent within and across types. Following the Linux and ThreadX conventions, use lower case for code file names and function names with underscore word separators where needed. Always verify case-consistency when developing in Windows, because the sloppiness that Windows allows will not fly when trying to build on Linux. Don't make a habit of mixing cases and relying on Windows to let you get away with it. Ganssle: We've known how to name things for 250 years. Carl Linnaeus taught scientists to start with the general and work towards the specific. Kingdom, Phylum, Class, Order, Family, Genus, Species. Since in the West we read left-to-right, seeing the Kingdom first gets us in the general arena, and as our eyes scan rightward more specificity ensues. So read_timer is a really lousy name. Better: timer_read. timer_write. timer_initialize. A real system probably has multiple timers, so use timer0_read, timer0_write. Or even better, timer_tick_read, timer_tick_write. The Linnaean taxonomy has worked well for centuries, so why not use a proven approach? Does a name have a physical parameter associated with it? If so, append the units. What does the variable "velocity" mean? Is it in feet/second, meters/second... or furlongs per fortnight? Much better is "velocity_mps", where mps was defined as meters/second in the header file. TypesPrefer uint8_t over char unless it is specifically for ASCII text. C++ AddendumautoMake very limited use of the auto keyword, for specific cases, because it reduces readability. A good use of it might be creating an iterator for a loop. |