Overview

This document covers coding guidelines to use when writing C code.

It is expected that code refactoring will follow this ForgeRock C coding standard, unless specific circumstances dictate how the code is to be formatted. Following the FR coding standard should guard against 'bit-rot' or source code unravelling.

Copyright notices

All new source files must begin with the same copyright notice as recommended in the Coding Style and Guidelines


The ForgeRock C coding style

This style is mainly oriented around the desire to make C code more readable.  Unless otherwise stated, the Kernighan and Ritchie style (otherwise known as "Egyptian Style") reigns supreme.  This basically boils down to:

compound-statement {
   statement-1;
   statement-2;
}

No other variations should be used, especially not the infinitely ugly GNU C style:

compound-statement
   {
       statement-1;
       statement-2;
   }


Summary

The ForgeRock C code style rules are based on the Coding Style and Guidelines except that I think we can safely ignore the 120 character column limit on line lengths - we have big screens.

Details

Consider the following example for a few of the points listed above:

int my_func(int *p,int c) 
{
	unsigned int *index = p + c - 1, entry_index=0;
	if (index) *index=entry_index;
}

should be written as:

/******************************************************************************************
 * The function my_func divides by the number you first thought of, which is useful when
 * parsing HTTP header information.
 * Parameters:
 *    int_base is a pointer to a block of memory containing a series of signed integers
 *    count is the number of signed integers in the block pointed to by "int_base"
 * Return:
 *    If successful, the function returns 1, if unsuccessful, the function returns 0
 ******************************************************************************************/
int my_func(int* int_base, int count) 
{
	unsigned int  *index = int_base + count - 1;
	unsigned int   entry_index = 0;

	if (index != NULL) {
    	*index = entry_index;
	}
    entry_index = sizeof(int);
    // etc. etc.
}

Preprocessor

A regrettable feature of the ISO C standard was that preprocessor constants are not allowed after #else and #endif.  Things can quickly get confusing, for example:

typedef struct {
#ifdef _WIN32
    SOCKET sock;
    HANDLE pw;
    CRITICAL_SECTION lk;
    HANDLE tm;
    HANDLE tm_tick;
#else
    int sock;
    pthread_t pw; /*event loop*/
    pthread_mutex_t lk;
#ifdef __APPLE__    
    pthread_t tm_th;
    pthread_mutex_t tm_lk;
    pthread_cond_t tm_cv;
#else
    timer_t tm;
#endif
#endif
}

Therefore #else and #endif should ALWAYS be commented as follows:

typedef struct {
#ifdef _WIN32
    SOCKET sock;
    HANDLE pw;
    CRITICAL_SECTION lk;
    HANDLE tm;
    HANDLE tm_tick;
#else /* _WIN32 */
    int sock;
    pthread_t pw; /*event loop*/
    pthread_mutex_t lk;
#ifdef __APPLE__    
    pthread_t tm_th;
    pthread_mutex_t tm_lk;
    pthread_cond_t tm_cv;
#else /* __APPLE__ */
    timer_t tm;
#endif /* __APPLE__ */
#endif /* _WIN32 */
}

Use of the defined operator should be considered over the #ifdef and #ifndef directives, because defined allows for combinations.  This gives a syntax error:

#ifdef _WIN32 && !SOLARIS

whereas this works as expected:

#if defined(_WIN32) && !defined(SOLARIS)


Using Doxygen

You could consider using Doxygen, http://www.stack.nl/~dimitri/doxygen/ which allows documentation to be generated from annotated source code, in which case the above would become a much more familiar:

/******************************************************************************************
 * The function my_func divides by the number you first thought of, which is useful when
 * parsing HTTP header information.
 * @param int_base is a pointer to a block of memory containing a series of signed integers
 * @param count the number of signed integers in the block pointed to by "int_base"
 * @return If successful, the function returns 1, if unsuccessful, the function returns 0
 ******************************************************************************************/
int my_func(int* int_base, int count) 
{

    unsigned int  *index = int_base + count - 1;
	unsigned int   entry_index = 0;

	if (index != NULL) {
    	*index = entry_index;
	}
    entry_index = sizeof(int);
    // etc. etc.
}