Code Conventions for the C Programming Language

Naming

The naming of variables and functions must be explicit and clear.

If several words are used in the name, the first letter of the first word should be lower case while the other first letter of other words must be uppercase.

Example:

myGreatFunction
integerMatrix

Global variable (this is bad) should be named explicitly.

Tool to format the code

Thanks to the indent command (package indent under Debian & Ubuntu), it is possible to follow automatically most of the code conventions. The following command formats properly the code:

indent -npro --braces-after-if-line  -i4 -ts4 -sob -ss -ncs -sc --no-space-after-parentheses  -cp1 --no-tabs -bap -bad -npcs --dont-break-function-decl-args --dont-break-procedure-type -bli0 -l150 -il0 <files>

On Windows, you can find indent here.

To automatically call the formatting tool:

mv .git/hooks /tmp/
cd .git/
ln -s ../git_hooks/ hooks

Indent style

Variable creation / assignments

Spaces must be used in the variable creation.

Example:

int i = 0;
double j = 42;

Don't put multiple assignments on a single line either.

Another measure of the function is the number of local variables. They shouldn't exceed 5-10, or you're doing something wrong. Re-think the function, and split it into smaller pieces.
A human brain can generally easily keep track of about 7 different things, anything more and it gets confused. You know you're brilliant, but maybe you'd like to understand what you did 2 weeks from now.

Curly braces

Curly braces must be on the next line at the same level as the first character

Example:

if (i == 1) 
{

}
or
for (i=0; i < max; i++)
{

}

Even for a single instruction, braces must be used.

Example:

if (i > 0)
{
                mySingleOperation();
}

switch / case

The break should be at the same line as the series of instructions in a case section.

Example:

                switch (suffix) 
                {
                   case 'G':
                   case 'g':
                         mem <<= 30;
                         break;
                   case 'm':

Spaces in the operations

After every keyword (if, while, etc) of the C language, a space must be added.

Example:

if (i == 1)
while (i == 0)

So use a space after these keywords:

        if, switch, case, for, do, while

but not with sizeof, typeof, alignof, or attribute. E.g.,

        s = sizeof(struct file);

Do not add spaces around (inside) parenthesized expressions. This example is *bad*:

(bad)
        s = sizeof( struct file );

Use one space around (on each side of) most binary and ternary operators, such as any of these:

        =  +  -  <  >  *  /  %  |  &  ^  <=  >=  ==  !=  ?  :

but no space after unary operators:

        &  *  +  -  ~  !  sizeof  typeof  alignof  __attribute__  defined

no space before the postfix increment & decrement unary operators:

        ++  --

no space after the prefix increment & decrement unary operators:

        ++  --

and no space around the '.' and "->" structure member operators.

Do not leave trailing whitespace at the ends of lines.

defines and ifdef

ifdef should be only used for multi platform aspect.

define must be written in uppercase.

Example:

#define PI 3.14

However, note that enums are preferred when defining several related constants and generally, inline functions are preferable to macros resembling functions.

Functions

A function, without variable declaration, should be no more than an editor page long (about 50 lines).

Comments

Any functions must have a Doxygen formatted comment.

Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment: it's much better to write the code so that the _working_ is obvious, and it's a waste of time to explain badly written code.

Generally, you want your comments to tell WHAT your code does, not HOW.

Use comment styles The preferred style for long (multi-line) comments is:

        /*
         * This is the preferred style for multi-line
         * comments in the Linux kernel source code.
         * Please use it consistently.
         *
         * Description:  A column of asterisks on the left side,
         * with beginning and ending almost-blank lines.
         */

Static functions

If a function is private to a file, the function should be declared as static.

Ternary operator

Ternary operator should be used only for small tests. Imbrication of ternary operators are forbidden.

headers

location

Several kind of headers into Scilab which should be stored at different places:

include

For headers file, especially those that will be used by other modules, only include other headers that are mandatory for the declaration. Example :

#ifndef __MYHEADER_H__
#define __MYHEADER_H__

#include "BOOL.h"
#include "machine.h"

void myFunctionTakingBOOL(BOOL _bIn);
#endif /* !__MYHEADER_H__ */

In this case BOOL.h is mandatory for the header itself, but machine.h is not. Better include machine.h in the associated sources where it is mandatory.

Messages

All messages to the user must be normalized to follow convention. See Localization in English - Standard messages

C++

Most of the coding style of C++ are based on C one.

C++ header

The C++ header should not contain code except if the code stays in one line.

license block

The standard license block is the following one:

/*
 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) Scilab Enterprises - 20xx-2012 - Firstname LASTNAME
 * 
 * This file must be used under the terms of the CeCILL.
 * This source file is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at    
 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 *
 */

public: Code Conventions for the C Programming Language (last edited 2012-12-05 15:42:33 by clement.david@scilab-enterprises.com)