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
- Use 4 spaces per indentation level.
- Tabs or Spaces?
- Never mix tabs and spaces.
- Code indented with a mixture of tabs and spaces should be converted to using spaces exclusively.
- For new projects, spaces-only must be used over tabs. Most editors have features that make this easy to do.
- Lines should have no trailing whitespace at the end.
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:
local to a module modules/<name>/src/c/*.h
internal to Scilab and use by other modules modules/<name>/includes
available in Scilab binary. They are also stored in modules/<name>/includes and must be explicitly added into Makefile.am. See SEP 35 (note: update this file if more headers are installed).
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 license block should be at the top of the file (1st line)
- Each time a change occurs in the file, the year should be updated.
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
*
*/