[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

9. Functions

assertions
Begin every function with a set of assertions that verify its argument values. Consider calling a function to do a detailed sanity check of any ADTs passed as arguments. Check magic numbers in ADTs for sure. Break up a single long assert() invocation into multiple shorter ones, both for readability and for more-specific reports as to which assertion triggered.

initializers
Be careful with initializers for local variables. They are evaluated before assertions so they offer another opportunity to screw up.

parameter order
In the absence of good reasons for another order, the following parameter order is preferred:

  1. this pointer.
  2. Input-only parameters.
  3. Input/output parameters.
  4. Output-only parameters.
  5. Status parameter.

order
Within a file, public functions should come first, in the order that they are declared in the header file, followed by private functions. Private functions should be in one or more separate pages (separated by formfeed characters) in logical groups. A commonly useful way to divide groups is by "level", with high-level functions first, followed by groups of progressively lower-level functions. This makes it easy for the program's reader to see the top-down structure by reading from top to bottom.

prototypes
Always use prototype style for function definitions. Prototype every public function in its respective header file.

Prototypes for static functions should either all go at the top of the file, separated into groups by blank lines, or they should appear at the top of each page of functions.

Don't comment individual prototypes, but a comment on each group of prototypes is often appropriate.

Don't use parameter names in prototypes, except when there is considerable danger of confusion. If you use parameter names in public header files, don't forget to use the proper name prefix. Proper use of types along with const can often make the purpose of parameters clear without any need for names. For example, each parameter's purpose should be clear in this prototype, even without names: void copy_string (void *, const void *, size_t);

const
Use const aggressively on pointer parameters to functions. Whether to use const for double-pointer parameters (const char **, etc.) is debatable, because double pointers whose targets have different qualifiers are not compatible, forcing casts in many cases. (See Steve Summit's C FAQ, question 10.11, for more information.)

comments
Short, straightforward functions do not need any comments besides the one preceding it that explains its interface. Longer functions should be divided into logical groups of statements by blank lines and each group should have a brief comment that explains its purpose.

Especially tricky functions should be rewritten until they are clear. If this is not possible for whatever reason, detailed explanatory comments are a second choice.

algorithms
If the algorithms used in a function are published in a journal or book or on a webpage, etc., give a full source citation. If the functions in a file all use algorithms from the same source, cite it in a comment near the beginning of the file.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Ben Pfaff on September, 11 2001 using texi2html