Invisio C/C++ Coding Standard
General Requirements
When generating or modifying C/C++ code:
- Follow the Invisio coding standard.
- Minimize unrelated formatting changes.
- Preserve existing external third-party code style.
- Use spaces only, never tabs.
- Indentation is 4 spaces.
- Opening braces use attached style.
- Braces are mandatory for all control statements.
- Internal functions must be declared static.
- Use const wherever applicable.
- All function arguments shall be named.
- Do not introduce new style variations.
- For session SQL workflows, available tables are:
todos,todo_deps,inbox_entries.
AStyle Formatting
The codebase is formatted using:
--indent=spaces=4 --suffix=.InvisioStyleErr --keep-one-line-statements --indent-switches --add-braces --style=attach --A2 --keep-one-line-blocks
Generated code shall already conform to these rules.
Naming Conventions
Variables
Use camel case.
Examples:
uint16_t theRedHorse; uint16_t readOkByte; uint16_t readOKbyte;
Acronyms
Acronyms are uppercase.
Examples:
UARTreadByte UARTcomLink UARTmask SPIwriteByte
Group Prefixes
When grouping is useful:
UART_readByte UART_writeByte SPI_readByte SPI_writeByte
Numbers
Numbers are written directly without underscores.
Examples:
testSPI1layer testSPI0order HBO0readByte
Avoid additional underscores around numbers.
Type Naming
Use the following suffixes:
typedefName_t structName_s enumName_e unionName_u
Examples:
typedef uint16_t value_t;
typedef struct { uint16_t value; } settings_s;
typedef enum { LEFT, RIGHT } position_e;
Defines
Defines are uppercase.
#define THE_RED_HORSE (1)
Always place parentheses around define values.
Correct:
#define UART_TIMEOUT_MS (100)
Incorrect:
#define UART_TIMEOUT_MS 100
Doxygen Comments
File Header
/**
- @file the_read_horse.c
- Description if applicable */
Function Declaration
/**
- Function
- @param in pointer to input
- @param out pointer to output
- @ingroup groupName */ void function(uint16_t *in, uint16_t *out);
Single-Line Doxygen
/// Description #define THEREDHORSE (1)
or
#define THEREDHORSE (1) ///< Description
Header File Structure
Order shall be:
- Doxygen file comment
- Include guard
- Includes
- File-wide defines
- Typedefs
- Structures
- Global variable declarations using extern
- Function declarations
- End include guard
Example:
#ifndef THE_RED_HORSE_H_ #define THE_RED_HORSE_H_
#include "typedef.h"
#define MAX_COUNT (10)
typedef uint16_t counter_t;
extern uint16_t globalCounter;
void readData(uint16_t *buffer);
#endif // THE_RED_HORSE_H_
Source File Structure
Order shall be:
- Doxygen file comment
- Includes
- Defines
- Typedefs
- Structures
- Global variables
- Internal function declarations
- Function definitions
Do not place extern declarations in .c files.
Functions
Internal functions must be static.
static uint16_t calculateChecksum(uint16_t value);
Use const when applicable.
static uint16_t calculateChecksum(const uint8_t *buffer, uint16_t length);
Example:
uint16_t readData(uint16_t in1, uint16_t in2) { uint16_t i = 0;
if (i == 0) {
/* code */
} else {
/* code */
}
i++;
return i;
}
Control Statements
Braces are always required.
Correct:
if (condition) { action(); }
Incorrect:
if (condition) action();
One-line blocks are allowed:
if ((timerClockFreq == 64000000) && (baudRate == 115200)) { timerPeriodTimesOnePointFive = 675; return; }
Boolean Conditions
Conditions must evaluate explicitly to a Boolean expression.
Incorrect:
while (count)
Correct:
while (count != 0)
Correct:
if (enabled == TRUE)
For Loops
for (i = 0; i < 10; i++) { /* code */ }
While Loops
while (condition) { /* code */ }
do { /* code */ } while (condition);
Switch Statements
Use indented cases.
Always include a default case.
Default shall be last.
Fall-through is not allowed when executable code exists between cases.
switch (condition) { case ABC: case DEF: doSomething(); break;
case XYZ:
doSomethingElse();
break;
default:
handleError();
break;
}
Expressions
Examples:
a += (c + d);
a = (a + b) / (c * d);
strp->field = str.fl - ((x & MASK) >> DISP);
Do not mix unrelated data types on the same expression line.
Pointer Style
Correct:
uint16_t *s; uint16_t *t; uint16_t *u;
Correct:
uint16_t *s, *t, *u;
Incorrect:
uint16_t* s, t, u;
Enums
typedef enum { LEFT = 0, ///< Left RIGHT = 1 ///< Right } position_e;
Structs
typedef struct { uint16_t var1; uint16_t var2; } structName_s;
Strings
Reserve space for the NULL terminator explicitly.
uint8_t myString[10 + 1];
Global Variables
- Avoid direct access when possible.
- Provide wrapper functions for read-only access.
- Use extern only in header files.
- Never place static variables in header files.
File and Folder Names
- Spaces are not allowed.
- Use the project's camel-case naming rules.
- Matching .c and .h files shall be located in the same folder.
- Group related files into folders when appropriate.
External Code
When importing external source files:
- Preserve the original code style.
- Do not reformat external code.
When copying snippets into project files:
- Convert the snippet to Invisio style.
- Add a comment indicating the original source.