-
Notifications
You must be signed in to change notification settings - Fork 9
Coding Convention
Files should have the following structure, in following order:
The purpose of the file is described within block comments (see paragraph about comments). Important! If a file has more than one purpose, then you might have to divide your code into more files. One file, one purpose!
Header files for standard C libraries are placed first, followed by “our own” header files. Example:
#include <stdlib.h> //standard library
#include “mylib.h”
Naming convention should follow the same format as specified for data types in inttypes.h: uint32_t
Example of type definition:
typedef struct {
uint32_t baud_rate;
uint32_t parity;
} uart_settings_t;
Global variables should only be used when it’s absolutely necessary.
Besides these conventions there’s also some general “common sense” when programming in C. It’s good follow the basic rules of what to put in a header file and what to put in a C file. Remember to always prevent multiple inclusion of header files. Example (foobar.h):
#ifndef FOOBAR_H
#define FOOBAR_H
//here comes code
#endif
Always place variable declarations in the beginning of the function.
Comments should describe WHY the code is programmed in a certain way, rather than HOW it’s been done or WHAT is happening. Example (HOW / WHAT):
x++; //increments the variable x with 1.
Example (WHY):
x++; //count character
Other important information to put within comments is: authors, version, date, bug information, etc. Use your imagination and common sense. If you use good semantics in your code then comments might even be redundant. Use comments only when needed.
Single line comments are used when comments are short enough to fit on one line:
//this is a short comment!
Block comments should be used when single line comments aren't appropriate, i.e when the comment can't fit on one line. Example:
/*
* This is a block comment!
* This type of comment is ideal for longer descriptions...
*/
Block comments should also be used above functions and especially in the beginning of a file, but in those cases you must follow a document standard. See Doxygen documentation.
Block comment to put in the beginning of a file
/**
* \file filename.c
* \brief Pretty nice code. Bla bla....
* \details This class is used to demonstrate a number of section commands.
* \author John Doe
* \author Jan Doe
* \version 4.1a
* \date 1990-2011
* \pre First initialize the system.
* \bug Not all memory is freed when deleting an object of this class.
* \warning Improper use can crash your application
* \copyright GNU Public License.
*/
Watch result: http://www.stack.nl/%7Edimitri/doxygen/manual/examples/author/html/class_some_nice_class.html
There's more to come! We must add guidelines for functions!
///@cond INTERNAL
// Code that should not be documented by doxygen
///@endcond
Identifiers for variables and functions are written in lowercase only and contain underscores between each “word”. For example:
int number_of_elements;
void get_number_of_elements(void);
Note that void is used in the function prototype when arguments shouldn’t be accepted by the function! If you have a problem with naming a function, which can lead to bad semantics, then it might be an indication of that the function has too much “responsibility”. If that’s the case, then you have to re-design your code. Example of bad code:
void end_transmission_and_close_file(void);
Same rules as above:
uart.h
lcd_driver.c
Names of defines and macros are written in uppercase only and contain underscores between each “word”. For example:
#define NUMBER_OF_ELEMENTS 10
To make a clear distinction between pointers and other variables, identifiers for pointers must have a prefix (”p_”). The asterisk must shall For example:For clarification reasons the names of pointers should have a “p” followed by an underscore as to not confuse these for normal variables. Also the asterisk for any pointer should be positioned right next to its pointer variable. For example:
int number;
int *p_number;
Note that the asterisk is written together with the variable identifier!
The starting bracket for all functions and other blocks of code (ex: if, while, struct) is placed on the same row:
void foobar(int a, int b) {
if (a == b) {
// code..
} else {
// more code..
}
}
Note that brackets are used even for single line statements in the if-else-statement!
Code should be restricted to a width of 80 columns and it is advised to keep functions within 25 rows (max. 50 rows). If a statement becomes wider than 80 columns, the code is continued on a new line starting from the same position as the start of the statement. For example (bad example, but you get the point!):
if (a == b &&
b == c) {
}
The width of an indentation is 4 characters.
If a function gets longer than 50 rows, then you should think about re-design your code. Make sure that your function only has one purpose (one responsibility).
Use a whitespace of one space character in expressions. Example:
if (a == b &&
b == c) {
}
Read more on this page: API Convention
- Choice of tools and rationale behind it
- How to set up the project
- Integrating Doxygen with Eclipse
- Integrating a serial output window with Eclipse
- Standard System Initialization