NASPRO - The 'NASPRO Architecture for Sound PROcessing'

User login

Who's online

There are currently 0 users and 0 guests online.

Syndicate

Syndicate content

Valid XHTML 1.0 Strict
Valid CSS
Viewable with Any Browser

Commenting

I hope it's needless to say that commenting is one of the most important issues when programming, especially in cooperative FLOSS projects; anyway it's always good to remember a couple of key points on how to get this work done well.

General rules

Obviously, all comments should be written in English and should be as informative, unambiguous and brief as possible.

In most cases comments should explain what the code does but not how, since the code itself should be clear enough for other developers to understand; only the few times when this is not possible (when using some clever trick, etc.) having some explaining comments is desirable.

Never use C99 style comments (// ...) since these are not part of the ISO/ANSI C standard (only use /* ... */).

Macros and functions

As we said earlier, Doxygen is used to build automatically generated documentation, and it uses comments to extrapolate the informations needed. Take a look at the "Doxygen Manual" for an introduction to Doxygen.

All functions and all macros (except the ones strictly related to the build system and the ones used to avoid header reinclusion) have to be documented using Doxygen comments. A good example is worth a thousand words:

/*! \brief	The \c PI constant (approximated to \c 3.1415). */
#define PI 3.1415

/*!
 *  \brief	Converts \c x from degrees to radians.
 *
 *  \param	x	The value to convert.
 *  \return	\c x in radians.
 */
#define DEG_TO_RAD(x) ((x) * PI / 180.0)

/*!
 *  \brief	Normalizes an angle expressed in radians.
 *
 *  \param	x	The value to normalize.
 *  \return	The normalized value of \c x (a value in \f$[0.0, 2 * PI)\f$).
 *
 *  \warning	Use only for values near to or included into the \f$[0.0, 360.0)\f$
 *          	interval.
 *  \sa		\c normalize_deg().
 */
float
normalize_rad(float x);

/*!
 *  \brief	Normalizes an angle expressed in degrees.
 *
 *  \param	x	The value to normalize.
 *  \return	The normalized value of \c x (a value in \f$[0.0, 360.0)\f$).
 *
 *  \warning	Use only for values near to or included into the \f$[0.0, 360.0)\f$
 *          	interval.
 *  \sa		\c normalize_rad().
 */
float
normalize_deg(float x);

...

/*!
 *  \brief	Normalization operation for \c{float}s.
 *
 *  This function is useful when you have some kind of periodic data (\c x)
 *  you want to be "normalized", meaning that you want the correspondent value
 *  inside a given range (\f$[min, max)\f$) whose length is the period size.
 *
 *  \param	x	The value to normalize.
 *  \param	min	The minimum interval value.
 *  \param	max	The maximum interval value.
 *  \return	A number in the interval \f$[min, max)\f$.
 *
 *  \warning	The algorithm used by this function has \f$O(n)\f$ complexity,
 *          	where \f$n = floor((x - min) / (max - min))\f$ if \f$x > max\f$,
 *          	or \f$n = floor((min - x) / (2 * PI))\f$ if \code \f$x < min\f$;
 *          	so only use it for values expected to be quasi normalized.
 *  \warning	Ensure that \f$max > min\f$ and that \c x is neither a NaN
 *          	nor an infinite before calling this function.
 */
float
_normalize(float x, float min, float max)
{

	if (x >= min)
		while (x >= max)
			x -= max - min;
	else
		while (x < min)
			x += max - min;

	return x;
}

float
normalize_rad(float x)
{
	return _normalize(x, 0.0, 2 * PI);
}

float
normalize_deg(float x)
{
	return _normalize(x, 0.0, 360.0);
}

...

Claryfing all the single points of this style would take years, so just refer to it in case of indecision. The most important things to notice are that:

  • long descriptions, warnings, see also references are optional but should be used whenever possible;
  • parameters and return values have to be always documented when present;
  • normal multiple line comments have a different layout from multiple line Doxygen comments;
  • there is no need to document the same function twice: just put the Doxygen comment where it is "first seen" (in order of precedence: public headers, private headers, source files).

Types

Types too must be properly documented. Again, let's show how it is to be done with an example:

/*! \brief Point in the three-dimensional Cartesian coordinate system. */
struct point_cartesian
  {
	/*! \brief X coordinate. */
	float x;

	/*! \brief Y coordinate. */
	float y;

	/*! \brief Z coordinate. */
	float z;
  };

/*! \brief Triangle (opaque type). */
typedef struct triangle *triangle_t;

This little piece of code shows the very few rules to follow:

  • all members of a struct and all constants of an enum have to be documented and there should be only one of them per line;
  • when declaring an opaque type, its description should clearly state that;
  • a longer description is often unneeded.
Copyright © 2007, 2008 Stefano D'Angelo