This is a real, live coding standard for Planetweb, a company that does embedded systems - different language, different concerns, different standards.

 

Recommended C Style and Coding Standards (7.23.01)

 

This document is based on an updated version of the Indian Hill C Style and Coding Standards paper. It describes recommended coding practices for C programming here at Our Company. All new code written should conform to these rules. Of course, standards cannot cover all situations. Experience and professional judgment count for much. Nonetheless, these guidelines should be followed unless there is compelling reason to violate them.

 

Many of the style choices here are somewhat arbitrary. That some will chafe is understandable. However, after coding to them for a while, they will come to seem comfortable and natural to you. The goal of these standards is to increase readability, ensure platform independence, improve clarity and, above all, to simplify maintenance. To meet these goals it is essential that all programmers conform to the standard.

 

In the event that you are performing maintenance, please bear in mind that mixed coding style is harder to maintain than bad coding style. When changing existing code it is better to conform to the style (indentation, bracing, etc) of the existing code that it is to blindly follow this document. Unless, of course, you are making wholesale changes – this represents an excellent opportunity to bring old code up to date.

 

File Naming Conventions

 

 

Program Files

The suggested order of sections for a program file is as follows:

  1. File identification.  The name of the file and the CVS keyword $Header$.
  2. Copyright information. Copy this boilerplate from another file and make the appropriate substitutions for year, etc. Suggested minimum: Copyright 2001 Our Company, Inc.  All Rights Reserved.
  3. A prologue that tells what is in the file. A description of the purpose of the objects in the file (whether they be functions, external data declarations or definitions, or something else) is more useful than a list of the object names. The prologue may optionally contain author(s), references, etc.
  4. Any header file includes should be next. If the include is for a non-obvious reason, the reason should be commented. In most cases, standard C library include files should be first, followed by PW system include files.
  5. Any defines and typedefs that apply to the file as a whole are next.
  6. Next come the global (external) data declarations, usually in the order: non-static globals, static globals. If a set of defines applies to a particular piece of global data (such as a flags word), the defines should be immediately after the data declaration or embedded in structure declarations, indented to put the defines one level deeper than the first keyword of the declaration to which they apply.
  7. The functions come next, and should be in some sort of meaningful order. Like functions should appear together. Considerable judgment is called for here. If defining large numbers of essentially independent utility functions, consider alphabetical order.
  8. The CVS revision log should be the last item in the file. If you don’t know how to do this, look at an existing file.

 

Header Files

#ifndef PW_EXAMPLE_H

#define PW_EXAMPLE_H

…body of example.h file

#endif                          // PW_EXAMPLE_H

 

 

Comments

The comments should describe what is happening, how it is being done, what parameters mean, which globals are used and which are modified, and any restrictions or bugs. Avoid, however, comments that are clear from the code, as such information rapidly gets out of date. Comments that disagree with the code are of negative value. Short comments should be what comments, such as “compute mean value”, rather than how comments such as “sum of values divided by n”.

·        Comments should justify offensive code. The justification should be that something bad will happen if inoffensive code is used. Just making code faster is not enough to rationalize a hack; the performance must be shown to be unacceptable without the hack. The comment should explain the unacceptable behavior and describe why the hack is a “good” fix.

 

 

Declarations

 

 

Function Declarations

 

 

Simple Statements

 

 

Compound Statements

A compound statement is a list of statements enclosed by braces. There are many common ways of formatting the braces. Be consistent with your local standard, if you have one, or pick one and use it consistently. When editing someone else's code, always use the style used in that code.

#define FOO(arg) do { bar(arg); baz(arg); } while (0)

Note the missing semicolon:  This forces a semicolon to be inserted by the user of the macro, and makes the macro safe for an unbracketed if statement.  Forcing semicolons to be used also ensures proper behavior by auto-indenters.

#ifdef FOOBAR

#define FOO(arg) { bar(arg); }

#else

#define FOO(arg)

#endif

 

if (expr)

            statement;

else

            FOO(x)

++x;

Note that on systems where FOOBAR is not defined the statement ++x; will only get executed when expr is false. If the macro had been written with the do {} while (0) style (and the semicolon added), this code would be correct.

 

 

Anti-Bugging

passing pointers around. I just tracked down a compiler warning where a

pointer to an "Sint" was being passed as an argument to a routine that was

expecting a "Sint32 *". While on systems where an Sint gets compiled as a

32 bit value this won't cause a problem, that is NOT true of all systems. If

you get compiler warnings because of mis-matched arguments, PLEASE fix them before checking the code in!