My Coding Style Guidelines
$Id: coding_style.html,v 1.3 2000/05/09 05:57:59 sshah Exp sshah $
|
"He reacquainted me with a powerful and flexible language that can be used
to insert helpful comments between code. It's called English, and I've come
to appreciate its usefulness."
|
|
-- Craig Hunt, TCP/IP Network Administration
|
General Comments
This document describes the C programming style guidelines for
my source code.
In general: APPLY COMMON SENSE LIBERALLY. If you are unsure as
to whether your code is understandable by others, ask others. Never
assume. We would all prefer to take 5 minutes and answer your question
than have to scratch our heads for 5 hours while we try to debug your
code.
Syntax Style Guidelines
- Use the GNU style guidelines unless explicitly told otherwise. You
can find those guidelines at http://www.gnu.org/prep/standards_toc.html.
- Use four character indents.
- The open curly brace ('{') should be on the same line as the start
of a block, except when declaring functions. e.g.
if (x == y) {
do_something();
}
- Do not use single character variable names unless it is an index to
a loop. (e.g. for (i=1;i...))
- Typedef's must end in a _t.
- #define names must be in all caps. No other variable types may
use a variable name with all caps.
- Never use lines greater than 80 columns. Remember that strings can
be broken up into two separate lines like so:
printf ("This is a very very very very very long string, "
"which cannot fit on one line. But this is okay.");
- If you inherit a piece of code that is in another style. Keep the
original style. Do not waste your time and energy trying to convert
it because more than likely you will break it in the process. If
you're not sure about a particular case, ASK.
- Header files should not contain the complete code to a function.
- Header files should never allow recursive includes to
work. i.e. they should start with lines like #ifndef
__MY_HEADER_FILE_H__ and end with #endif /*
__MY_HEADER_FILE_H__ */.
- When you need to take a block of code out, DO NOT COMMENT IT
OUT. Instead, use #ifdef/#endif. e.g. #ifdef
REMOVE_UNTIL_COFFEE_PROTOCOL_IS_DONE.
- The question mark operator is to be avoided.
- All switch statements must have a default clause.
- Function names should be ANSI style, all in one line with return
types on the same line.
- There must be a comment at the beginning of every function. It
should include: the function name what it does, its inputs, and the
meaning of its return codes.
- Comment variable usage.
- Write correct comments and keep it updated with the code.
Semantic Guidelines
- Assume all code will need to be understandable by someone else at
4am when you're not around to answer questions.
- Comment all code liberally. If anyone complains that you comment
too much, tell your manager so that person can be transferred to
accounting.
- Feel free to throw README files into the source tree to explain a
particular file or design or anything. Be sure the README's are
checked in along with the rest of the code.
- Optimize your writing style for human readability. Do not think
you are smarter than the compiler or that you need to "help" the
compiler generate more efficient code. This means using plenty of
parenthesis and breaking up your code into multiple lines if each
line is doing something completely different.
- NO MAGIC NUMBERS. Never assume that a number will remain constant
through the life of the product. Also never assume that someone will
understand why the limits are what they are. If you must pick an
arbitrary limit (e.g. maximum string size), comment in the code that
the number is arbitrary.
- All string functions must have some method of guaranteeing that
they will stop and not crash the system. This means no blind strcpy or
sprintf function calls. Instead, use strncpy and snprintf.
- Minimize scope. If you need to add a global variable stop and ask
yourself whether you really need it or not. Understand that you
are adding the global namespace pollution by putting it there. Also be
sure you can do a complete tree rebuild with your addition.
- Prototypes should contain names of variables along with their types.
- Do not code to save space at the expense of performance. Wasting a
few bytes to store a simple value (e.g. using an int to store a bool)
is much better than bit packing. Bit packing results in many extra
instructions generated by the compiler which in most instances is
unnecessary. The obvious exception to this rule is those cases where
you are constructing a specific structure which requires bit
packing. e.g. TCP headers.
- Always check for error codes. Always be able to handle all error
codes.
- Use typecasting only when necessary. Do not use typecasting for
the sole purpose of getting rid of a warning.
- Any use of goto should be explained.
- All #if lines should be commented.
- Use #if (OPTION_A) instead of #ifdef.
Compiling and Makefiles
- All projects should be compilable by simply typing "make".
- All Makefiles must be GNU make compliant.
- All C programs must compile clean with the following flags: -ansi,
-pendantic, and -Wall. Any warnings that are generated MUST be
explained in the documentation. Exceptions given to standard C header
files that generate warnings.
General Comments
- Remember that the nature of the product requires us to think in
terms of both high availability and high throughput. WE MUST
NEVER CRASH! We shoust also never have reason to call
exit(). All error conditions must be gracefully handled.
- Fix bugs as they are found. Never say you will get back to a bug
later "when you have time," because you will never have time
later. (Murphy's Law of Bug Hunting) Furthermore, the magnitude of the
bug will only increase as more people build on your check-in.
- Recommended reading: Writing Solid Code by Steve McConnel.
$Id: coding_style.html,v 1.3 2000/05/09 05:57:59 sshah Exp sshah $