- C++17 is the minimum supported standard.
- C++20 features may be used only if guarded by
#if __cplusplus >= 202002L. - All code must compile cleanly with
-Wall -Wextra -Wpedantic -Werrorunder GCC 12 and Clang 14.
Every source and header file must start with:
// Copyright (c) 2026 Matt Jones. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0.Followed by:
- File-level
// fusa:reqannotation listing requirements implemented here. - Standard library
#includes, sorted alphabetically, separated from project includes by a blank line. - Project
#includes, sorted alphabetically. - Namespace declarations.
| Entity | Convention | Example |
|---|---|---|
| Types | PascalCase |
ScheduleEntry |
| Functions | snake_case |
calc_checksum |
| Variables | snake_case |
checksum_type |
| Constants | kPascalCase |
kLINMaxDataLen |
| Private members | snake_case_ |
closed_ |
| Namespaces | snake_case |
lin::virt |
| Macros | SCREAMING_SNAKE_CASE |
(avoid macros) |
| Enum values | PascalCase |
ChecksumType::Enhanced |
- All LIN types live in
namespace lin. - Virtual bus lives in
namespace lin::virt. - Safety types live in
namespace lin::safety. - LDF parser lives in
namespace lin::ldf. - Master node lives in
namespace lin::master. - Slave node lives in
namespace lin::slave. - RELAY types live in
namespace relay(shared with cpp-CAN). - Anonymous namespaces are preferred over
staticfor file-local helpers.
- Use exceptions for programmer errors (invalid arguments, contract violations).
- Use
std::error_codefor expected runtime failures in APIs. - Never use
abort(),assert(), orexit()in library code — only in tests. - Error types must inherit from
std::runtime_errororstd::system_error. - Every public function that can fail must document its failure modes.
- All public APIs must document their thread-safety guarantees.
- Use
std::shared_mutexfor read-heavy, write-rare data (subscriptions). - Use
std::atomicfor metrics counters to avoid lock contention. - Never hold a lock across an external callback invocation.
- Prefer
std::unique_ptrfor exclusive ownership. - Use
std::shared_ptronly when shared ownership is genuinely needed. - No raw
new/deletein library code. - No
malloc/free.
Every function that implements a requirement from .fusa-reqs.json must carry:
// fusa:req REQ-LIN-001Multiple requirements on the same function:
// fusa:req REQ-LIN-001 REQ-LIN-002Every TEST_CASE or SECTION that verifies a requirement must carry:
// fusa:test REQ-LIN-001The project's .clang-tidy enables:
clang-analyzer-*bugprone-*modernize-use-overridemodernize-use-nullptrcppcoreguidelines-no-malloc
All warnings from enabled checks must be resolved (not suppressed) before merge.
- Every public API must have a corresponding unit test.
- Line coverage must remain at or above 70%.
- Tests must not have external dependencies (no network, no filesystem access
except reading test fixtures from
testdata/). - Use Catch2
REQUIREfor assertions that must pass for the test to be valid; useCHECKfor non-fatal assertions. - Each
TEST_CASEmust carry a unique tag[lin],[virtual],[e2e],[ldf],[master],[slave],[relay], or[cli].
- All public types and functions must have Doxygen-style
///comments. - Comments must explain why, not what.
- Do not comment-out dead code — delete it.