4 KiB
4 KiB
Vessel C Code Standards
1. Naming Conventions
1.1 Prefixing
- All public symbols (functions, variables, constants, macros, types) must be prefixed with
vs_
orVS_
. - All private structure members must:
- Be prefixed with
_
- Be placed at the bottom of the structure definition if possible.
- Be prefixed with
1.2 Naming Style
- Use
snake_case
for all identifiers: variables, functions, struct/union/enum names. - Constants and macros should be
UPPER_SNAKE_CASE
. - Iterators should use
idx
,jdx
,kdx
rather thani
,j
,k
for clarity. - All variables should be at least 2-3 characters.
- Objects should use
PascalCase
.
1.3 Function Naming
- All functions operating on a specific type (e.g.,
vs_HMap
) must include that type in the name:
vs_HMap_insert(...);
vs_HMap_destroy(...);
- Functions working with hashmaps or other container types must include:
- A corresponding
init_
anddestroy_
function - Preferably a
typedef
alias for the type
- A corresponding
2. Code Formatting
2.1 Formatting Tools
- Use
clang-format
andclang-tidy
with the project-supplied configuration files. - All contributors must format code before submission.
2.2 Bracing and Indentation
- Use braces even for single-line
if
,for
, orwhile
blocks unless it is the most inner layer and obviously safe.
if (cond) {
...
}
- Indentation is 4 spaces. Do not use tabs.
2.3 Line Length
- Limit lines to 100 characters unless breaking the line reduces readability.
3. Type and Memory Safety
3.1 Typing
- Prefer fixed-width types from
<stdint.h>
orvessel/def.h
:int32_t
,uint16_t
, etc.- Avoid
int
and other ambiguous-width types unless interfacing with APIs that require them. size_t
andssize_t
are allowed.
- Avoid type casting where possible, especially to smaller types.
3.2 Immutability
- Default to
const
-correctness. Treat objects as immutable unless mutation is clearly needed.
3.3 Structure Passing
- Always pass structures by pointer, not by value.
3.4 Dereferencing
- Avoid two or larger-level dereferencing (e.g.,
**obj
,obj->a->b
, ...) unless implementing a proxy pattern or absolutely necessary.
4. Style and Syntax
4.1 Comments
- Use C-style block comments only:
/* ... */
. Avoid C++-style//
comments - All public headers should use
Doxygen
-compatible comments:
/**
* @brief Brief description.
* @param foo Description of parameter foo.
* @return Description of return value.
*/
4.2 Constants & Bitsets
- Prefer bitsets like
(1 << N)
over hex or decimal values, explicitly casting to the target type:
#define FLAG_WRITE ((uint16_t)(1 << 0))
#define FLAG_READ ((uint16_t)(1 << 1))
5. Logging and Debugging
- Logging must use the global logging interface.
- Logs should be:
- Clear
- Prefixed by the function name
6. Standard Compliance and Portability
- Avoid reliance on non-portable features:
- Don't use
_POSIX_C_SOURCE
or compiler-specific extensions unless strictly necessary. - Prefer ANSI-compatible syntax.
- Don't use
7. Function and API Design
7.1 Dual Interfaces for Strings
- Functions that accept strings must provide both:
- A null-terminated (
char *
) version - A sized (
char *buf, size_t len
) version
- A null-terminated (
7.2 Structure Initialization & Destruction
- All dynamic or heap-using structures must have:
vs_type_init(...)
vs_type_destroy(...)
7.3 Error Reporting
- For simple functions, basic error indicators like returning
-1
or a falsy value (e.g.,NULL
orFalse
) are sufficient for error handling. - For functions that operate on objects, error handling and reporting should be managed through the
vessel/error.h
API, ensuring consistent error management across the codebase.
7.4 Include guards
- All headers must include a header guard following the convention of:
#ifndef VESSEL_FILE_H_
#define VESSEL_FILE_H_
...
#endif /* VESSEL_FILE_H_ */