C Coding Guideline
This document is prepared to help developers about how to write the code. It contains different types of code language rules. These rules make writing, maintaining, reviewing the code easier. Also some rules increase portability, …
Horizontal Spacing
Tab usage with space
In most projects, we are using number of spaces instead of using the tab character(\t). Most cases 4 spaces could be use for tab key. This can be set from settings of most IDE’s.
Unary Operators
The unary operators are written with no space between the operator and the operand.
!value
~bits
++i
j--
(CPU_INT32U)x
*ptr
&x
sizeof(x)
Binary Operators
The binary operators (and the ternary operator) are written with at least on space between the operator and operands.
c1 = c2;
x + y
i += 2;
n > 0 ? n : -n
a < b
c >= 2
Expressions
Expressions within parentheses are written with no space after the opening parenthesis and no space before the closing parenthesis.
x = (a + b) * c;
if and if-else statements
if(x < y)
{
return -1;
}
else if(x > y)
{
return 1;
}
else
{
return 0;
}
while, do-while and for loops
while(condition)
{
}
do
{
} while(condition);
for(int i = 0, j = argc; i < argc; i++, j--)
{
}
switch-case statements
switch(number)
{
case RED:
return GREEN;
case GREEN:
return BLUE;
case BLUE:
return RED;
default:
return BLACK;
}
Naming Convention
In this section, there are some naming convention rules for C language.
These rules can be applied to:
- Public and local functions
- Typedef struct and enumeration
- Public and local variables
Public and Local Functions
Naming convention of functions is important because if there is a good naming for functions, it would be easy to read the code.
Public Functions
Public functions can be called from another files. So it is better to put some prefix before function name:
Example:
void network_stackMgmt(int code);
bool uartIO_txEnable(void);
Local Functions
Local functions can be called only from inside the file that the function is written. So there is no need to put a prefix before function name:
static void clearBuffer(void);
static bool getState(int index);
Typedef Struct and Enumeration
Naming convention of typedef structures and enumerations is important because if there is a good naming, it would be easy to read the code.
Struct
If there is a good naming for the structure definition, it would be easy to read the code.
struct s_deviceManagerRing {
uint8 link;
char mac[18];
};
Typedef Struct
If there is a good naming for the typedef structure definition, it would be easy to read the code.
typedef struct {
uint64_t mac;
char ipServer[48];
uint16_t portServer;
uint16_t portClient;
} ts_gsmNet;
Enumeration
İf there is a good naming for the enumeration definition, it would be easy to read the code.
enum e_deviceManagerStates {
E_DEVICE_MANAGER_INIT = 0,
E_DEVICE_MANAGER_START,
E_DEVICE_MANAGER_STOP,
};
Typedef Enumeration
If there is a good naming for the typedef enumeration definition, it would be easy to read the code.
typedef enum {
E_DIO_E_INPUT_1 = 0,
} te_dioInputs;
Public and Local Variables
Naming convention of variables is important because if there is a good naming for variables, it would be easy to read the code.
Public Variables
Public variables can be used from another files. So it is important to have a prefix before the variable name like this:
char uartIO_respReady[6] = "READY";
char lon_respSet[6] = "SET\r\n";
Local Variables
Local variables can be used from only the file that they are written inside. So it is not important to have a prefix before the variable name.
static bool up;
static uint64_t local;
static uint8_t button;
File Content
It is better to have sections inside the file in every coding language. In this section there are some rules about file content.
File content should be separated with some comment blocks. So this way, it would be easy to find what we are looking for in the file content.
To get a documentation from the comments, Doxygen format is used for comments.
Doxygen Comment Blocks
This section is prepared to give some information about doxygen comment blocks and how to write them.
Function Documentation
Here is one example:
/**
* \brief Initializes the UART handle.
* \param config UART configuration string (ex. "COM1:115200,N,8,1")
* \return Returns a handle to the newly opened UART
*/
UART_HandleTypeDef *uartOpen(char *config)
{
...
}
Variable Documentation
Here is one example:
static uint8 mode[2]; /**< Uart mode * /
Define Documentation
Here is one example:
/* UART configuration */
#define UARTIO_EVEN FALSE /**< Even parity */
#define UARTIO_PARITY FALSE /**< Parity enabled */
#define UARTIO_WORDLEN E_AHI_UART_WORD_LEN_8 /**< Word length */
#define UARTIO_ONESTOP TRUE /**< One stop bit */
File Heading
A comment block must be placed at the beginning of each source code file (both code and header files) containing;
- Filename
- Brief(short description)
- Details(detailed description)
- Remarks(additional remarks)
Here is one example comment block:
/**
* \file Filename
* \brief A brief description, one sentence, one line.
* \details A detailed description of the file scope, it can span over
* multiple lines, can be omitted.
* \remarks Additional remarks.
*/
File Layout
Both source and header files must be divided by sections:
- INCLUDE FILES
- MACRO DEFINITIONS
- LOCAL DATA TYPES
- LOCAL CONSTANTS
- VARIABLES
- LOCAL FUNCTION PROTOTYPES
- PUBLIC FUNCTION
- LOCAL FUNCTION
Even if the section is empty, it’s comment block must be added to the file:
/*----------------------------< Section Name >--------------------------*/
Include Section
The INCLUDE FILES section should include all necessary header files.
/*------------------------------< Includes >-----------------------------*/
#include <iostream>
#include <thread>
Macro Definitions Section
The MACRO DEFINITIONS section should include all necessary macro defines.
/*--------------------------< Macro Definitions >-----------------------*/
#ifndef TRACE_APP
#define TRACE_APP TRUE
#endif
Local Constants Section
The LOCAL CONSTANTS section should include all necessary constant variables.
/*--------------------------< Constants >-------------------------------*/
const uint32 msecCount = 1800;
Local Data Types Section
The LOCAL DATA TYPES section should include all necessary data type definitions.
/*----------------------------< Typedefs >-------------------------------*/
typedef struct
{
bool rts; /**< Current RTS setting */
bool cts; /**< Current CTS setting */
} ts_uart;
Local Variables Section
The LOCAL VARIABLES section should include all necessary local(static) variables.
/*---------------------------< Variables >------------------------------*/
static uint8 uart = APP_UART_0;
Local Function Prototypes Section
The LOCAL FUNCTION PROTOTYPES section should include all necessary local(static) function prototypes.
/*-------------------------< Prototypes >-----------------------------*/
static void delayMsec(uint32 period);
Public Function Section
The PUBLIC FUNCTION section should include all necessary public function declarations.
/*---------------------------< Public Function >------------------------*/
void dio_outputInitialise(void)
{
...
}
Local Functions Section
The LOCAL FUNCTION section should include all necessary local(static) function declarations.
/*-------------------------< Private Function >--------------------------*/
static void initialiseApp(void)
{
...
}
Abbreviations
Please refer to here to see abbreviations.