|
libmemalloc 0.0.0-alpha
The Magic of Memory Transmutation
|
Use this standard when writing or reviewing C code for reusable modules. It defines naming, formatting, control flow, ownership, error handling, concurrency, and the evidence required for performance changes.
Start with the language and target contract, then use the index to find a rule. Each control states its requirement and provides examples or review guidance. The appendices collect restricted APIs and complete implementation examples.
Read C Module Architecture for module boundaries and build composition. Use Common C Pitfalls to connect a failure scenario with prevention controls, verification designs, and sources.
Use C Compliance and Assurance for assessment and release claims. Follow C Formal Verification for proof campaigns and their assumptions, source mapping, and acceptance criteria.
These three guides define project policy for reusable C modules. Supporting sources and their scope appear in the research record in Common C Pitfalls. The policy is not a replacement for the C implementation contract or for a product's hazard and threat analyses.
The documents have distinct owners:
| Document | Owns | Does not own |
|---|---|---|
| C Code Standard | Local C rules, API contracts, memory, concurrency, arithmetic, the CBAN register, and evidence-gated optimization | The module graph or product certification |
| C Module Architecture | Module ownership, callback boundaries, approved lower-layer exceptions, adapters, builds, linking, exports, and lifecycle composition | A second copy of local C or vulnerability rules |
| Common C Pitfalls | Failure scenarios, review/test designs, control mapping, and external source/evidence records | Additional hidden normative implementation rules |
Use the stable CSTYLE-*, CMOD-*, CPIT-*, CPERF-*, and CBAN-* identifiers in reviews and verification records. Record the repository commit when an audit needs the exact wording of a rule. Existing short and full-ID anchors preserve links when section titles change.
A must or an imperative instruction is a project requirement. Should is an expected default that needs a recorded rationale when not followed. May is permission. Classification is independent of obligation: a style violation and a use-after-free are not equivalent risks even when both violate a must-rule.
| Class | Scope |
|---|---|
| CORRECTNESS | Defined operations and satisfied functional contracts |
| SAFETY | Predictable failure/timing/state behavior under a product hazard model |
| SECURITY | Protection of trust boundaries, secrets, authority, and executable inputs |
| ARCHITECTURE | Ownership, permitted dependencies, interfaces, and lifecycle boundaries |
| PORTABILITY | Explicit dialect, representation, implementation, and ABI assumptions |
| ANALYZABILITY | Checkable requirements and reproducible review/test evidence |
| PROJECT_STYLE | Naming and presentation choices, not language guarantees |
When requirements conflict, first honor the selected language and platform semantics, then the approved product safety/security constraints, then this set, then documented local style. Do not silently resolve a conflict by choosing the more convenient document. Correct the rule or obtain an approved deviation. No local rule can make undefined behavior defined.
A deviation record contains the rule and repository commit, affected paths/variants, reason, alternatives considered, risk, compensating controls, tests/evidence, owner, independent approver where required, and review/expiry condition. A linter suppression must reference that record. Approval is scoped; it does not rewrite the global policy. Revisit it after changes to compiler, ABI, dependencies, concurrency, or threat/hazard assumptions.
This standard treats C as an imperative systems language with compile-time typing and weak checks. Execution proceeds through statements that change state by assignment, function calls, selection, iteration, and object-lifetime operations. Code must make state transitions, side effects, ownership transfers, and failure paths visible to reviewers, compilers, static analyzers, and tests.
C assigns types during translation but permits implicit arithmetic conversions, explicit casts, pointer arithmetic, manual storage management, and direct access to object representations. Its execution model also distinguishes implementation-defined, unspecified, and undefined behavior. The project therefore constrains pointers, conversions, macros, control flow, object lifetime, storage duration, and standard-library use. Target-dependent assumptions must be explicit rather than inferred from behavior observed on one machine.
The coding vocabulary draws on the structured C tradition described in the second edition of Kernighan and Ritchie's The C Programming Language, which covers ANSI C. The current language baseline is ISO/IEC 9899:2024 / C23. MISRA C, SEI CERT C, and ISO/IEC TS 17961 inform the project's safety and security controls. These references serve different purposes: the language standard defines C semantics, while this document establishes the implementation practices required by the project.
New qualified targets must use an explicitly selected C23 dialect. A compatibility profile must identify its language version, supported features, and restrictions; it must not silently downgrade the language baseline or imply support for features that the toolchain does not implement. Builds requiring unsupported features must be rejected.
Each target profile must record the compiler, C library or available runtime, linker, architecture, compilation and linking flags, integer widths, byte size, alignment requirements, endianness, and ABI options. These declarations define the environment in which the implementation is built and evaluated.
The worked sources use a C17-compatible subset so the same implementation can also be compiled and tested under a declared C17 compatibility profile. This compatibility applies to those sources and the stated profile. It does not establish complete C23 support for the toolchain.
The project requires Single Entry, Single Exit (SESE) at function level. Functions must use one entry point, a visible ret variable, one normal exit label named function_output, and one return path. Resource cleanup and error propagation must converge on that exit. Hidden exits, early returns, uncontrolled jumps, and ad hoc cleanup paths are prohibited.
This convention gives reviewers a consistent location to inspect resource release and the final result of an operation. State changes and ownership transitions must remain explicit along every path leading to function_output; a shared exit does not replace argument validation, lifetime reasoning, or correct cleanup conditions.
The theoretical background includes Böhm and Jacopini's structured-flow work, Dijkstra's argument against unrestricted goto, the treatment of single-entry/single-exit regions in Ferrante, Ottenstein, and Warren's program-dependence-graph work, and subsequent program-structure-tree research. The specific ret and function_output convention is the project's implementation policy.
Each execution profile must define the facilities it provides and the restrictions that apply to them. A freestanding or RTOS profile must identify its actual runtime facilities. A hard-real-time profile must prohibit hidden allocation, unbounded waits, and recursion in critical paths and require target-specific timing and stack evidence. A security-boundary profile must include the applicable interpreter, authentication, and update controls. A host-test profile may permit controlled fault injection and fatal test assertions; its negative tests must exercise defined error paths rather than execute undefined behavior.
The worked example uses a hosted Linux/ELF profile with eight-bit bytes, ASCII decimal input, and available uint8_t and uint32_t types. Heap allocation occurs through injected allocator ports, and module instances require external synchronization.
In that example profile, debug builds deliberately abort when an internal invariant assertion fails. Release builds remove those assertions while retaining runtime validation of external inputs and handling of recoverable errors. Deliberate debug or test termination is a declared profile behavior, not an alternative recoverable error path under the SESE convention.
The example implements no network service, authentication system, cryptography, ISR, DMA, garbage collector, or concurrent reclamation algorithm. Rules governing those facilities remain part of the standard, but the example does not provide implementation evidence for them.
Compiler diagnostics, tests, static analysis, and sanitizers provide evidence within the scope of the selected profile and the checks performed. Passing results do not establish MISRA compliance, complete CERT coverage, ISO 26262 approval, absence of vulnerabilities, a real-time bound, or a formal proof. Verification records must distinguish the behavior examined from requirements that remain outside the example or test scope.
Follow this standard unless a module defines a stricter local rule. A local rule may strengthen the requirements; it must not silently relax the language baseline, control-flow discipline, ownership contracts, or execution-profile restrictions.
Contextual examples illustrate one contract within a larger implementation. Apply the enclosing function's declarations, validation, ownership, cleanup, and execution-profile requirements before using a fragment. Layout and diagnostic blocks describe structure or expected output; they are not executable C.
C fences display indentation with spaces at the repository's eight-column tab stops. The example checker compares this display form with clang-format output before compiling the extracted files.
Examples marked noncompliant or do not copy demonstrate a failure. Keep them out of executable tests when they invoke undefined behavior. The complete sources in the appendices provide the surrounding implementation. Verification records must identify which sources and configurations a check ran.
Class: PROJECT_STYLE. Obligation: project requirement.
Use one naming vocabulary throughout public headers, implementations, tests, and generated project interfaces. The rules in this section are project style, except where a rule also identifies an implementation-reserved namespace. A naming convention does not establish symbol visibility or ownership.
Layout example (not executable):
src/network/network_client.c include/network/network_client.h
Noncompliant fragment (do not copy):
Layout, diagnostic, or contract example. This block is not executable C.
src/Thing/DoStuff.C include/misc.h
Class: PROJECT_STYLE. Obligation: project requirement.
Use snake_case. Use explicit unit suffixes when the variable stores a measurable quantity.
Contextual C example:
int my_variable = 0; size_t user_count = 0u; size_t buffer_size_bytes = 0u; uint32_t timeout_ms = 0u; size_t payload_bytes = 0u;
Class: PROJECT_STYLE. Obligation: project requirement.
Use MODULE_lowerCamelCase for public functions and module_lowerCamelCase for module-internal or private functions. Private functions also require static; spelling does not determine linkage or exports. Hosted main and externally prescribed entry points retain the name required by their environment. In application main.c, every helper and state object is private; use static for file-scope helpers and objects, while main retains its required non-static entry linkage. Record other naming exceptions at the owning adapter.
Contextual C example:
static int module_parseValue(int my_arg); static inline int util_parseString(int my_arg); int NETWORK_sendPacket(int my_arg);
Class: PROJECT_STYLE. Obligation: project requirement.
Use descriptive snake_case typedef names with the project or module prefix. The inherited _t suffix is a project convention, not an ISO C requirement. A strict platform namespace profile may replace that suffix consistently before publishing a new API. Do not rename an existing ABI without migration review. Do not hide an owning pointer behind a typedef that conceals its pointer nature; opaque object types and explicit callback typedefs are allowed.
Contextual C example:
typedef enum MemoryStateMachine
{
MEM_STATE_STOP = 0u,
MEM_STATE_START = 1u,
MEM_STATE_IDLE = 2u,
MEM_STATE_MAX = 3u
} mem_state_t;
typedef struct IntWrapper
{
int value;
} int_wrapper_t;
typedef void (*callback_fn_t)(int_wrapper_t *item);
Class: PROJECT_STYLE. Obligation: project requirement.
Use UpperCamelCase for struct and enum tags.
Contextual C example:
typedef struct IntWrapper
{
int value;
} int_wrapper_t;
typedef enum UserStatus
{
USER_ACTIVE = 0u,
USER_INACTIVE = 1u,
USER_MAX = 2u
} user_status_t;
Class: PROJECT_STYLE. Obligation: project requirement.
Use SCREAMING_CASE with a module prefix.
Contextual C example:
typedef enum MemoryStateMachine
{
MEM_STATE_STOP = 0u,
MEM_STATE_START = 1u,
MEM_STATE_IDLE = 2u,
MEM_STATE_MAX = 3u
} mem_state_t;
Class: PROJECT_STYLE. Obligation: project requirement.
Use explicit values for protocol enums. A sequential enum that is used as an array index may end in *_MAX as a count, provided the sequence starts at zero and has no gaps. The sentinel is not a valid runtime value. Sparse enums and bitmasks need membership or allowed-bit validation instead of a count check. An unsigned literal suffix does not by itself fix an enum's underlying type or binary layout. Use a specified representation at a wire or stable ABI boundary.
Contextual C example:
typedef enum MemoryStateMachine
{
MEM_STATE_STOP = 0u,
MEM_STATE_START = 1u,
MEM_STATE_IDLE = 2u,
MEM_STATE_SLEEP = 3u,
/* element count */
MEM_STATE_MAX = 4u
} mem_state_t;
Class: PROJECT_STYLE. Obligation: project requirement.
Use snake_case.
Contextual C example:
goto function_output; function_output : return ret;
Class: PORTABILITY / PROJECT_STYLE. Obligation: project requirement.
Use SCREAMING_CASE for macros. Do not define identifiers reserved to the C implementation, including leading double underscores and an underscore followed by an uppercase letter. Avoid leading underscores in all project names. Compiler-provided tokens may appear in compiler adapters. A trailing __ is the inherited marker for project portability macros; it does not make such a macro portable or suitable for a strict C++ namespace profile.
Contextual C example:
#define MAX_LEN ((size_t)(10U)) #define BUFFER_ALIGN ((size_t)(8U)) #define VERSION_CHECK__ ((uint32_t)(100U))
Class: PROJECT_STYLE. Obligation: project requirement.
Use snake_case and end with _.
Contextual C example:
#define STRINGIFY_TOKEN(token_) #token_
Class: PROJECT_STYLE. Obligation: project requirement.
Use snake_case for .c and .h file names.
Layout example (not executable):
memory_manager.c memory_manager.h network_socket.c network_socket.h packet_parser.c
Class: PROJECT_STYLE. Obligation: project requirement.
Prefer snake_case for directory names. This keeps module structure consistent with file naming and makes paths more predictable.
Short directory names such as src, net, mem, or util are also acceptable when they are already well understood in the project context.
Layout example (not executable):
. ├── src/ ├── include/ ├── memory_manager/ ├── network_layer/ └── file_system/
Class: PROJECT_STYLE. Obligation: project requirement.
For repository names, prefer one of these patterns:
For this project family, prefer snake_case unless an external hosting or distribution convention requires a different style.
Layout example (not executable):
packet_router memory_manager network_stack packet-router memory-manager network-stack sqlite redis systemd
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Lifecycle verbs carry project-wide meaning. A public API must use the verb that matches the resource transition performed by the function.
Use configure, commit, submit, load, or another specific verb when an operation does more than a setter. This rule extends the action and predicate semantics in CSTYLE-146.
Contextual C example:
int DEVICE_create(device_t **device); int DEVICE_init(device_t *device, const device_config_t *config); int DEVICE_bind(device_t *device, const device_port_t *port); int DEVICE_start(device_t *device); int DEVICE_stop(device_t *device); int DEVICE_reset(device_t *device); int DEVICE_deinit(device_t *device); void DEVICE_destroy(device_t **device); int DEVICE_getState(const device_t *device, device_state_t *state); int DEVICE_setMode(device_t *device, device_mode_t mode);
Noncompliant fragment (do not copy):
int DEVICE_init(device_t **device); /* allocates a new object */ int DEVICE_stop(device_t **device); /* frees the object */ int DEVICE_setState(device_t *device); /* performs a full reconfiguration */
Class: PROJECT_STYLE. Obligation: project requirement.
Apply the source-format rules in this section consistently. Automate formatting where possible without changing semantics.
Contextual C example:
if (is_ready)
value = next_value;
Noncompliant fragment (do not copy):
if(is_ready){value=next_value;}
Class: PROJECT_STYLE. Obligation: project requirement.
Keep maintained C source and header lines within 80 columns. Do not shorten identifiers or hide checks merely to meet this limit. Generated code, reference URLs, Markdown tables, tool output, and verbatim external declarations are not subject to this source-format rule. Record a local exception when a source line cannot be split without changing meaning.
Contextual C example:
ret = NETWORK_sendPacket(packet, packet_size_bytes, timeout_ms);
Noncompliant fragment (do not copy):
ret = NETWORK_sendPacket(packet, packet_size_bytes, timeout_ms, retry_count, diagnostics, context, allocator);
Class: PROJECT_STYLE. Obligation: project requirement.
Break long lines at logical boundaries:
Contextual C example:
int ret = EXIT_SUCCESS;
ret = EX_performComplexCalculation(input_value_a, input_value_b, input_value_c,
config_ptr);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PROJECT_STYLE. Obligation: project requirement.
Indent continuation lines consistently.
Contextual C example:
bool is_ready = false; is_ready = has_input && has_capacity && is_initialized;
Class: PROJECT_STYLE. Obligation: project requirement.
Split long string literals with explicit concatenation.
Contextual C example:
const char *msg = "This is a very long error message "
"that needs to be split across multiple lines.";
Contextual C example:
LOG_error("firmware image signature verification failed");
Class: PROJECT_STYLE. Obligation: project requirement.
Use Allman braces for C functions and compound statement bodies required by CSTYLE-022. A compound literal may place its opening brace after a line break. Preprocessor definitions and initializer lists are formatted according to their own syntax. This is a formatting choice; it is not a claim of stronger memory safety.
Contextual C example:
int EX_example(void)
{
int ret = EXIT_SUCCESS;
if (condition)
{
EX_doSomething();
EX_doSomething();
}
else
{
EX_doSomethingElse();
EX_doSomethingElse();
}
function_output:
return ret;
}
Noncompliant fragment (do not copy):
int EX_example(void) {
int ret = EXIT_SUCCESS;
if (condition) {
EX_doSomething();
EX_doSomething();
} else {
EX_doSomethingElse();
EX_doSomethingElse();
}
function_output:
return ret;
}
Class: PROJECT_STYLE. Obligation: project requirement.
Put spaces around binary and assignment operators and after commas. Keep unary operators with their operands and member access without surrounding spaces. Format pointer declarators consistently. These spacing rules do not change operator precedence, evaluation order, or the declaration's type.
Contextual C example:
#define EX_DEFAULT_VALUE ((int)(10U))
bool is_equal = false;
bool is_ready = false;
is_equal = (value_a == value_b);
is_ready = is_enabled && has_input;
if (value == EX_DEFAULT_VALUE)
EX_doSomething();
Noncompliant fragment (do not copy):
#define EX_DEFAULT_VALUE ((int)(10U))
int sum=a+b;
int product=x*y;
if(value==EX_DEFAULT_VALUE)
EX_doSomething();
Class: PROJECT_STYLE. Obligation: project requirement.
Parenthesize mixed logical or arithmetic expressions where it clarifies precedence. Do not add casts or parentheses that conceal an overflow, evaluation order, or type-conversion issue. Simple assignments, comparisons, and a single arithmetic operation do not need redundant outer parentheses.
Contextual C example:
#define EX_VALUE_A ((uint32_t)(1U))
#define EX_VALUE_B ((uint32_t)(2U))
#define EX_VALUE_C ((uint32_t)(3U))
#define EX_VALUE_D ((uint32_t)(1U))
uint32_t total = 0u;
total = ((EX_VALUE_A + EX_VALUE_B) * (EX_VALUE_C - EX_VALUE_D));
if ((value_x > value_y) && (value_y != 0))
EX_doSomething();
Noncompliant fragment (do not copy):
int total = value_a + value_b * value_c - value_d;
if (value_x > value_y && value_y != 0)
EX_doSomething();
Class: PROJECT_STYLE. Obligation: project requirement.
An if body containing one simple statement on one physical line must omit braces. Put that statement on the next line, indented eight columns. Never put it on the condition's line. Apply the same rule to a simple else body. An else if chain is allowed.
Use braces when a branch has multiple statements, a wrapped statement, a declaration, or nested control flow. Keep braces around nested conditionals to prevent a dangling else. Comments that describe a simple body belong above its condition; a comment does not justify misleading indentation. Every for, while, and do body keeps braces, even for one statement. Do not remove braces that establish a required scope or lifetime. Macros and conditional compilation require separate review.
This is an approved libmemalloc adaptation of the imported Coil rule. Clang formatting preserves braces; clang-tidy and policy fixtures check required braces. Review checks unnecessary braces in simple branches and logical grouping; a formatter cannot decide whether operations are related.
Contextual C example:
size_t index = 0u;
if (flag)
EX_doSomething();
for (index = 0u; index < count; index++)
{
flags[index] = false;
}
if (flag)
{
EX_doFirst();
EX_doSecond();
}
Noncompliant fragment (do not copy):
#define EX_ERROR_VALUE (-EINVAL)
size_t index = 0u;
if (flag) return EX_ERROR_VALUE;
for (index = 0u; index < count; index++) sum += array[index];
if (flag)
EX_doFirst();
EX_doSecond();
Class: PROJECT_STYLE. Obligation: project requirement.
Use exactly one empty line at each logical boundary. Do not use consecutive empty lines or whitespace-only lines. Keep related operations together rather than separating every statement.
Clang formatting enforces function separation and limits retained empty lines. Review must verify declaration boundaries and semantic groups. See CSTYLE-280 for the call/check exception.
Contextual C example:
int ret = 0;
size_t index = 0u;
request.count = count;
request.flags = flags;
statistics.last_count = count;
for (index = 0u; index < count; index++)
{
items[index].ready = false;
}
function_output : return ret;
Class: PROJECT_STYLE. Obligation: project requirement.
When a function result requires validation, store it and start its test on the very next physical line after the complete call. Do not insert an empty line, a comment, another call, or unrelated work between the call and its test. For a wrapped call, the test follows the line that closes the call. Do not embed the assignment in the condition or delay validation until after using an output.
Treat the call, its test, and its failure handling as one unit. Separate successive call/check units with exactly one empty line. Separate the completed unit from unrelated successful-path work with one empty line. Keep multiple assignments inside one failure handler together when they implement the same recovery action. A one-line goto body omits braces under CSTYLE-022.
Use the result convention required by the API: negative error, null pointer, boolean, or documented status. This rule does not invent a failure result for a void function. It does not permit extra early returns: preserve the single normal return through function_output required by CSTYLE-064. Separate the final return group as required by CSTYLE-279. Mandatory checks remain governed by CSTYLE-066 and CSTYLE-151; call/check adjacency and semantic grouping require review.
Contextual C example:
int ret = 0;
ret = EX_prepareRequest(&request);
if (ret < 0)
goto function_output;
ret = EX_submitRequest(&request);
if (ret < 0)
goto function_output;
statistics.completed++;
function_output : return ret;
Noncompliant fragment (do not copy):
ret = EX_prepareRequest(&request);
statistics.completed++;
if (ret < 0) goto function_output;
ret = EX_submitRequest(&request);
if (ret < 0)
{
goto function_output;
}
Class: PROJECT_STYLE. Obligation: project requirement.
Keep * attached to the variable name.
Contextual C example:
int data = 0; int *ptr1 = (int *)(NULL); int *ptr2 = (int *)(NULL); char *buffer = (char *)(NULL); int *const ptr = &data;
Noncompliant fragment (do not copy):
int* ptr1, ptr2; int * ptr1, * ptr2; int* const ptr = NULL;
Class: CORRECTNESS. Obligation: project requirement.
Use pointed-data const for read-only inputs and preserve qualifiers through adapters. A const pointer does not freeze its pointee, and a pointer to const does not prevent another valid alias from modifying the object. Do not cast away constness to write an object defined as const.
Apply CSTYLE-107 to automatic declarations. Use named constants or immutable file-scope tables for nonzero constant data rather than introducing a late local declaration or attempting to assign to a const object after validation.
Contextual example:
File-scope immutable definitions, not automatic declarations. They demonstrate pointed-to const and pointer const without violating the zero-like automatic-initialization rule. Mutable automatic pointers still start as typed NULL.
#define EX_READ_ONLY_VALUE ((int)(20U)) static const int read_only_value = EX_READ_ONLY_VALUE; static const int *const fixed_ptr = &read_only_value;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Declare exactly one object or function per declaration. A declaration must not mix pointer and non-pointer declarators or hide distinct initialization state in one statement.
This rule applies to local objects, file-scope objects, parameters declared in old-style definitions, and declarations in a for initializer.
Noncompliant fragment (do not copy):
int *buffer = (int *)(NULL), count = 0;
Contextual C example:
int *buffer = (int *)(NULL); int count = 0;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
An assignment must be the primary operation of its statement. Do not place an assignment inside a function argument, subscript, condition, return expression, initializer expression, or another assignment.
Related pitfalls:
Do not chain assignments. Repeat the state transition as separate statements when several objects intentionally receive the same value.
Noncompliant fragment (do not copy):
ret = EX_process(value = EX_readValue());
Contextual C example:
value = EX_readValue(); ret = EX_process(value);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
An increment or decrement operator must be the primary operation of a standalone statement or the update expression of a simple for loop. It must not participate in a larger expression.
The for update expression may contain one increment or decrement operation. A loop that advances several objects must use explicit statements in the loop body.
Noncompliant fragment (do not copy):
value = items[index++];
Contextual C example:
value = items[index]; index++;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Project identifiers, labels, macro names, file names, and directory names use ASCII unless a documented external interface requires another form. Comments and string literals may contain UTF-8 text when their consumer expects UTF-8.
Raw Unicode bidirectional formatting controls are prohibited in source text. Tests that need those code points must encode them with byte escapes or a project Unicode helper. CI should enable the strongest available compiler or text-linter diagnostic for bidirectional controls, such as GCC -Wbidi-chars=any,ucn.gcc-bidi-chars Unicode documents the spoofing risk of bidirectional text.unicode-security
Contextual C example:
const char *message = "Operation complete: \u2713"; const char *bidi_test = "\xe2\x80\xae";
Noncompliant fragment (do not copy):
int \u03B1 = 0; /* A raw bidirectional formatting character appears in this source line. */
Class: CORRECTNESS. Obligation: project requirement.
Keep interfaces self-contained and owned. Use the following header and representation controls together with the module architecture.
Contextual C example:
#include <stddef.h> #include <stdint.h> #include "module.h"
Noncompliant fragment (do not copy):
#include "../peer/src/private.h" #include "everything.h"
Class: CORRECTNESS. Obligation: project requirement.
Use unique, project-prefixed include guards in public and internal headers. Use #if !defined(NAME) followed by #define NAME and a closing #endif. Headers must supply the declarations of the types they expose without depending on an earlier include. Nonstandard #pragma once is not the portable baseline. Every project C header intended for C++ inclusion also owns the conditional C-linkage block in CMOD-019, inside its include guard. Keep any permitted dependency includes outside the linkage block.
Contextual C example:
#if !defined(APP_CONFIG_H)
#define APP_CONFIG_H
#include <stdint.h>
typedef struct AppConfig
{
uint32_t id;
} app_config_t;
#endif
Class: CORRECTNESS. Obligation: project requirement.
Use include guards to make repeated inclusion well-defined for the header. The guard name must not collide with another project, generated, third-party, or platform header. Guards prevent repeated processing; they do not fix circular interfaces, missing prerequisites, or incorrect declaration ownership.
Noncompliant fragment (do not copy):
#pragma once
#include <stdint.h>
typedef struct AppConfig
{
uint32_t id;
} app_config_t;
Class: CORRECTNESS. Obligation: project requirement.
In a module implementation, include its own public header first, then C standard headers, third-party headers where the adapter is their owner, and other directly used project headers. Separate and alphabetize each group. An application entry point without a matching header starts with its standard headers. Application main.c may directly include any needed standard, platform, third-party, module public/internal, contract, or adapter header under CMOD-021. Its own declarations remain private, except for the required hosted entry point. A source file is not an includable header and must not have an include guard. Include order must never be an ABI or compilation prerequisite.
Contextual C example:
#include <errno.h> #include <stdlib.h> #include <string.h> #include <openssl/ssl.h> #include "memory_manager.h" #include "network_socket.h" #include "packet_parser.h"
Noncompliant fragment (do not copy):
#include <stdlib.h> #include "packet_parser.h" #include "network_socket.h" #include <string.h> #include "memory_manager.h"
Class: CORRECTNESS. Obligation: project requirement.
Concentrate version-sensitive third-party calls in a named adapter. Give the adapter a project-owned contract for ownership, errors, capacity, and lifetime; a macro that merely renames a library call is not such a contract. Ordinary modules use the adapter's approved interface or an injected port, according to CMOD-003 and CMOD-050. Do not require wrappers for every ISO C operation. Dependency trust, pinning, and updates belong to CMOD-084.
Failure scenarios: CPIT-093, CPIT-099.
Source context: supply-chain.
Contextual C example:
#if !defined(SSL_WRAPPER_H)
#define SSL_WRAPPER_H
#include <errno.h>
#include <stdlib.h>
#include <openssl/ssl.h>
static inline int SSL_WRAP_ctxNew(SSL_CTX **ctx_out)
{
int ret = EXIT_SUCCESS;
SSL_CTX *ctx = (SSL_CTX *)(NULL);
if (ctx_out == (SSL_CTX **)(NULL))
{
ret = -EINVAL;
goto function_output;
}
if (*ctx_out != (SSL_CTX *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
ctx = SSL_CTX_new(TLS_client_method());
if (ctx == (SSL_CTX *)(NULL))
{
ret = -EIO;
goto function_output;
}
*ctx_out = ctx;
function_output:
return ret;
}
static inline int SSL_WRAP_ctxFree(SSL_CTX **ctx)
{
int ret = EXIT_SUCCESS;
if ((ctx != (SSL_CTX **)(NULL)) && (*ctx != (SSL_CTX *)(NULL)))
{
SSL_CTX_free(*ctx);
*ctx = (SSL_CTX *)(NULL);
}
function_output:
return ret;
}
#endif
Contextual C example:
#include <stdlib.h>
#include "ssl_wrapper.h"
int APP_main(void)
{
int ret = EXIT_SUCCESS;
int cleanup_ret = EXIT_SUCCESS;
SSL_CTX *ctx = (SSL_CTX *)(NULL);
ret = SSL_WRAP_ctxNew(&ctx);
if (ret != EXIT_SUCCESS)
goto function_output;
function_output:
cleanup_ret = SSL_WRAP_ctxFree(&ctx);
if ((ret == EXIT_SUCCESS) && (cleanup_ret != EXIT_SUCCESS))
ret = cleanup_ret;
return ret;
}
Class: CORRECTNESS. Obligation: project requirement.
Define a public contract only for supported behavior, not to expose implementation convenience.
Contextual C example:
#if !defined(MODULE_H) #define MODULE_H typedef struct Module module_t; int MODULE_start(module_t *module); #endif
Noncompliant fragment (do not copy):
#if !defined(MODULE_H) #define MODULE_H static int internal_state = 0; int module_privateHelper(void); #endif
Class: PROJECT_STYLE. Obligation: review trigger.
Review a source file above 1,000 lines or a header above 500 lines for weak cohesion and accidental public surface. These inherited thresholds are review triggers, not measurements of correctness. Split by responsibility, not by arbitrary line count. Record the review outcome when retaining a larger file.
Layout example (not executable):
parser.c: parsing only serializer.c: serialization only
Noncompliant fragment (do not copy):
Layout, diagnostic, or contract example. This block is not executable C.
protocol.c: parsing + TLS + storage + CLI + metrics + database
Class: ARCHITECTURE / CORRECTNESS. Obligation: project requirement.
Each module should have one clear responsibility.
Layout example (not executable):
module/storage/: owns storage state and storage operations
Noncompliant fragment (do not copy):
Layout, diagnostic, or contract example. This block is not executable C.
module/utils/: owns unrelated storage, networking, crypto, and UI logic
Class: ARCHITECTURE / CORRECTNESS. Obligation: project requirement.
Public headers contain the module contract: declarations, opaque types, required value DTOs, callback types, constants, and export annotations. They must not define mutable externally linked objects or expose private representation. Internal headers may contain the module's complete private types and cross-TU prototypes. An approved foundation header may contain a small static inline helper. Including a header does not authorize access to another module's state.
Noncompliant fragment (do not copy):
static int global_value = 0;
Class: CORRECTNESS. Obligation: project requirement.
A header must provide the types and declarations needed to parse its own interface. Compile it as the first include in a probe without prerequisite headers. A macro-only header may be followed by a harmless probe declaration to avoid an empty-translation-unit diagnostic; the probe must not supply a missing dependency. Test each supported public macro/ABI variant. Do not rely on an unrelated header having been included first.
Contextual C example:
#include "my_header.h"
int main(void)
{
int ret = 0;
function_output:
return ret;
}
Class: CORRECTNESS. Obligation: project requirement.
State the representation assumptions of public data and serialized values. Use the specific controls below.
Contextual C example:
typedef struct WireHeader
{
uint8_t version;
uint8_t flags;
uint16_t payload_size_le;
} wire_header_t;
Noncompliant fragment (do not copy):
typedef struct WireHeader
{
long version;
void *payload;
} wire_header_t;
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Use size_t for object sizes and capacities, ptrdiff_t for representable pointer differences, and fixed-width integer types when a specified width is part of the contract. Exact-width types are not guaranteed on every C target. A target profile must declare required integer widths, CHAR_BIT, alignment, byte order, and relevant ABI options. Check narrowing before conversion. Use project status values or map platform errors explicitly; do not assume all platforms assign the same numeric values to error names.
Contextual C example:
uint32_t register_value = 0u; uint16_t wire_length = 0u;
Noncompliant fragment (do not copy):
unsigned long register_value = 0ul; int wire_length = 0;
Class: CORRECTNESS. Obligation: project requirement.
Prefer an enum for a closed set of related states, commands, or modes. Use a macro or another qualified constant form when preprocessing, a bitmask, or a specified integer representation requires it. An enum documents a value domain but does not validate externally supplied integers. Use a count sentinel only for the zero-based contiguous case described in CSTYLE-007.
Contextual C example:
typedef enum DeviceState
{
DEVICE_STATE_OFF = 0u,
DEVICE_STATE_INIT = 1u,
DEVICE_STATE_RUN = 2u,
/*< Enum max value >*/
DEVICE_STATE_MAX = 3u
} device_state_t;
Noncompliant fragment (do not copy):
#define DEVICE_STATE_OFF (0u) #define DEVICE_STATE_INIT (1u) #define DEVICE_STATE_RUN (2u)
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Encode wire and persistent data field by field. Specify version, byte order, field widths, permitted values, lengths, reserved bits, and integrity policy. Do not write or deserialize a raw C struct, pointer, enum representation, or padding as a portable format. Fixed-width members do not remove struct padding or byte-order dependence. Decode into validated local values before committing runtime state. See the complete checked codec in the worked example.
Failure scenarios: CPIT-028.
Complete example: worked sources.
Noncompliant fragment (do not copy):
typedef struct Packet
{
uint32_t id;
uint16_t size;
} packet_t;
memcpy(packet_buffer, &packet, sizeof(packet));
Contextual C example:
#define PACKET_SERIALIZED_SIZE_BYTES ((size_t)(6U))
int PACKET_serialize(const packet_t *packet, uint8_t buffer[],
size_t buffer_size)
{
int ret = EXIT_SUCCESS;
size_t offset = 0u;
if ((packet == (const packet_t *)(NULL)) ||
(buffer == (uint8_t *)(NULL)))
{
ret = -EINVAL;
goto function_output;
}
if (buffer_size < PACKET_SERIALIZED_SIZE_BYTES)
{
ret = -ENOSPC;
goto function_output;
}
ret = BYTE_writeU32Be(buffer, buffer_size, &offset, packet->id);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = BYTE_writeU16Be(buffer, buffer_size, &offset, packet->size);
if (ret != EXIT_SUCCESS)
goto function_output;
function_output:
return ret;
}
Contextual C example:
int PACKET_serialize(const packet_t *packet, uint8_t buffer[]);
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Treat size, alignment, packing, enum representation, and calling conventions as ABI properties when objects cross a binary boundary. Measure padding when optimizing storage; do not reorder fields of an existing ABI casually. Do not use packed overlays for unaligned network data. Validate ABI layout with target checks where it is fixed. Field order alone is not an optimization or compatibility guarantee.
Contextual C example:
typedef struct Example
{
uint64_t timestamp;
uint32_t id;
uint16_t size;
uint8_t flags;
} example_t;
Contextual C example:
typedef struct Data
{
uint8_t flag;
uint8_t pad[3];
uint32_t value;
} data_t;
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Compare semantic fields, not entire struct object representations. Padding can make representation comparison differ from value comparison. memcmp is allowed for valid, non-secret byte sequences of the stated length; it is not a constant-time secret comparator. Do not replace ordered integer comparisons with subtraction that may overflow.
Contextual C example:
bool is_equal = false; is_equal = (data_a.flag == data_b.flag) && (data_a.value == data_b.value);
Class: ARCHITECTURE / CORRECTNESS. Obligation: project requirement.
Use an incomplete public object type when consumers do not need its layout. A constructor/destructor pair must specify allocator family and failure behavior. Caller-supplied opaque storage needs documented size, alignment, effective-type, and initialization rules; a byte array cast is not automatically valid storage. For stable binary APIs, define compatibility, struct-size negotiation, and feature/version rules. Do not infer ABI stability from source compatibility.
Contextual C example:
typedef struct Config config_t; int CONFIG_create(config_t **cfg_out); int CONFIG_destroy(config_t *cfg);
Contextual C example:
struct Config
{
int timeout;
int retries;
int flags;
};
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Bit-fields must not represent MMIO registers, serialized data, network protocols, persistent formats, or public ABI. Allocation order, alignment, packing, and the treatment of storage units depend on the implementation.
Every numeric bit-field width must use the lowercase unsigned suffix u, as required for enum values. Write : 1u, : 2u, or : 3u; never write an integer width without a suffix or use uppercase U.
Avoid mapping a register directly:
Use a fixed-width register value and named masks:
A purely internal structure may use bit-fields only with a documented justification. Such code must not depend on byte layout, bit allocation order, or raw copying, and the object must remain inside one compiler and ABI domain.
Noncompliant fragment (do not copy):
typedef struct Register
{
uint32_t enable : 1u;
uint32_t mode : 3u;
uint32_t status : 4u;
} register_t;
Contextual C example:
#define REG_ENABLE_MASK ((uint32_t)(1U << 0U))
#define REG_MODE_MAX ((uint32_t)(7U))
#define REG_MODE_MASK ((uint32_t)(7U << 1U))
#define REG_STATUS_MASK ((uint32_t)(15U << 4U))
uint32_t reg_value = 0u;
if (requested_mode <= REG_MODE_MAX)
{
reg_value = MMIO_read32(REG_CTRL_ADDRESS);
reg_value &= ~REG_MODE_MASK;
reg_value |= (requested_mode << 1u) & REG_MODE_MASK;
MMIO_write32(REG_CTRL_ADDRESS, reg_value);
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Use character types according to the data contract:
Whether plain char is signed must not affect numeric logic, range checks, shifts, indexing, checksums, measurements, or protocol values.
Avoid ambiguous binary declarations:
Prefer types that state the domain:
Noncompliant fragment (do not copy):
char raw_data[256]; char checksum; char temperature;
Contextual C example:
char text[256]; uint8_t raw_data[256]; uint8_t checksum = 0u; int16_t temperature_celsius = 0;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A union that represents alternative semantic values must have an explicit discriminator. Code may read only the member selected by that discriminator, and every state transition must update the member and discriminator together.
Prefer a tagged union:
Do not use a union to reinterpret an object representation:
Use memcpy() when code needs the bytes of a representation:
Contextual C example:
typedef enum ValueType
{
VALUE_TYPE_INT = 0u,
VALUE_TYPE_PTR = 1u,
/* element count */
VALUE_TYPE_MAX = 2u
} value_type_t;
typedef struct Value
{
value_type_t type;
union
{
int32_t int_value;
void *ptr_value;
} data;
} value_t;
Noncompliant fragment (do not copy):
union
{
float float_value;
uint32_t bits;
} value;
value.float_value = input;
bits = value.bits;
Contextual C example:
uint32_t bits = 0u; static_assert(sizeof(input) == sizeof(bits)); memcpy(&bits, &input, sizeof(bits));
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Flexible array members are prohibited in public ABI, MMIO mappings, serialized layouts, and persistent formats. Safety-critical core code requires a documented deviation before using one.
An approved internal flexible-array object must:
Prefer an explicit capacity contract:
Do not allocate or copy only the fixed header when payload storage is needed.
Contextual C example:
typedef struct Packet
{
size_t length;
size_t capacity;
uint8_t data[];
} packet_t;
packet_t *packet = (packet_t *)(NULL);
size_t alloc_size = 0u;
bool has_overflow = false;
has_overflow = ARITH_addSize(sizeof(*packet), payload_capacity, &alloc_size);
if (has_overflow)
{
ret = -ENOMEM;
goto function_output;
}
packet = (packet_t *)MEM_alloc(alloc_size);
if (packet == (packet_t *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
packet->length = 0u;
packet->capacity = payload_capacity;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Do not hide ordinary object pointers behind a typedef. Pointer typedefs obscure qualification and make declarations such as const buffer_t appear to protect the pointed bytes when they only qualify the pointer alias.
Prefer a typedef for the object type and spell the pointer explicitly:
An opaque handle may use a pointer typedef only at a reviewed external ABI boundary that cannot expose the pointed type. Project-owned module APIs prefer an incomplete object type and an explicit pointer.
Noncompliant fragment (do not copy):
typedef uint8_t *buffer_t; const buffer_t buffer = (buffer_t)(NULL);
Contextual C example:
typedef uint8_t byte_t; const byte_t *buffer = (const byte_t *)(NULL);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
An aggregate initializer containing a non-zero semantic value must name each initialized member. Positional aggregate initialization is permitted only for the all-zero initializer required by CSTYLE-107.
Designators make the source independent of unrelated member insertion and make the semantic mapping visible during ABI and configuration review.
Noncompliant fragment (do not copy):
static const config_t g_default_config = {1000u, 3u, true};
Contextual C example:
static const config_t g_default_config = {
.timeout_ms = 1000u,
.retry_count = 3u,
.is_enabled = true,
};
Class: PROJECT_POLICY. Apply the scope and requirement words below.
An invariant knowable during translation must be checked with static_assert or a project compatibility wrapper. Do not rely only on a comment or a runtime branch for a translation-time property.
Use translation-time checks for public layout, wire-format bounds, array counts, alignment, power-of-two parameters, enum sentinels, and assumptions shared with assembly or linker scripts. The expression must not depend on a side effect.
Contextual C example:
static_assert(sizeof(uint32_t) == 4u); static_assert(MEM_BLOCK_ALIGNMENT >= alignof(max_align_t)); static_assert((MEM_BLOCK_ALIGNMENT & (MEM_BLOCK_ALIGNMENT - 1u)) == 0u);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A string literal must be referenced only through a pointer-to-const character type. Code must not cast away that qualification or attempt to modify literal storage.
Use a writable array when mutation is required:
Contextual C example:
const char *message = "operation failed";
Contextual C example:
char message[] = "operation failed"; message[0] = 'O';
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Do not use anonymous struct or union members in project interfaces or ordinary production code. Give the aggregate type and containing member explicit names so ownership, active-member state, debugging, generated bindings, ABI review, and static analysis can refer to them unambiguously.
An external hardware or compiler adapter may mirror an unavoidable anonymous layout only under the compiler-extension and external-dependency boundary rules.
Contextual C example:
typedef union ValueData
{
uint32_t u32;
float f32;
} value_data_t;
Noncompliant fragment (do not copy):
struct Packet
{
union
{
uint32_t u32;
float f32;
};
};
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Wire, file, persistent, shared-memory, DMA, and hardware formats must state the byte order of every multi-byte integer. Convert between external and host order at the owning boundary. Internal semantic values use host order and must not be converted repeatedly as they cross ordinary helper functions.
Do not infer byte order from the build host, a union view, a cast, or the order of structure members. Use project conversion helpers whose names identify both width and direction. A conversion helper must define behavior for every supported host byte order and must be covered by big-endian and little-endian tests or equivalent byte-exact vectors.
Contextual C example:
length = WIRE_readU32Le(input);
Noncompliant fragment (do not copy):
memcpy(&length, input, sizeof(length)); /* native endian assumed */
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A byte buffer does not acquire the alignment, effective type, lifetime, or provenance of an integer or structure merely because it contains enough bytes. Potentially unaligned external storage must be decoded with a project load/store helper or memcpy() into a properly aligned typed object, followed by the required byte-order conversion.
Do not cast a packet, mapped file, packed field, device buffer, or arbitrary offset in raw storage to a wider pointer and dereference it. Linux documents that unaligned access can be transparent but slow, fault and require an expensive fixup, fault without recovery, or silently access different data on different architectures.linux-unaligned-access
Contextual example:
Include <string.h>. native_value is a uint32_t declared at entry; source_bytes has at least sizeof(native_value) readable bytes. Decode the agreed byte order separately; memcpy fixes alignment/aliasing access, not endianness.
memcpy(&native_value, source_bytes, sizeof(native_value));
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Every external text boundary must name its encoding and malformed-input policy. A UTF-8 boundary must validate well-formed UTF-8 before code interprets bytes as characters. Unicode requires a conforming process to treat ill-formed encoding sequences as an error condition rather than interpreting them as characters. unicode-standard
The boundary contract must state:
Do not infer encoding from the current locale, platform code page, or char signedness.
Compliant boundary:
The API contract for CONFIG_parseName states UTF-8, rejects malformed input, and defines input_bytes as encoded bytes.
Noncompliant boundary:
Contextual C example:
int CONFIG_parseName(const uint8_t *input, size_t input_bytes,
text_view_t *name);
Noncompliant fragment (do not copy):
int CONFIG_parseName(
const uint8_t *input,
size_t input_bytes,
text_view_t *name
); /* encoding and malformed-input behavior are unspecified */
Class: CORRECTNESS. Obligation: project requirement.
Keep preprocessor behavior explicit and reviewable. Feature logic and compiler adaptation must not silently change an ABI.
Contextual C example:
#define TIMEOUT_MS ((uint32_t)(100U)) #define MASK(bit_) ((uint32_t)(1U) << (bit_))
Noncompliant fragment (do not copy):
#define TIMEOUT_MS 100 #define MASK(bit) 1 << bit
Class: CORRECTNESS. Obligation: project requirement.
Parenthesize macro expressions and their value arguments. Use an explicit integer constant macro such as UINT32_C, or a checked, appropriate type when width matters. Do not force every literal through a narrowing cast. Literal suffix capitalization is a formatting convention, not a type-safety mechanism. sizeof, array bounds, and enum constants have distinct constant-expression requirements; test macros in the contexts where they are used.
Contextual C example:
#define MAX_COUNT ((size_t)(100U)) #define LARGE_VALUE ((uint64_t)(1000ULL)) #define PI_APPROX ((float)(3.14F)) #define BUFFER_SIZE ((size_t)(256U))
Class: CORRECTNESS. Obligation: project requirement.
Prefer functions or small approved static inline helpers for executable behavior. A statement macro must use the do { ... } while (0) pattern, must not evaluate a value argument more than once, and must not hide return, goto, locking, allocation, or ownership transfer. A caller must be able to review its side effects. GNU statement expressions are adapter-only extensions.
Contextual C example:
#define APP_ASSIGN_PAIR(first_ptr_, first_value_, second_ptr_, second_value_) \
do \
{ \
*(first_ptr_) = (first_value_); \
*(second_ptr_) = (second_value_); \
} \
while (0)
Contextual C example:
#define MIN_VALUE__(value_a_, value_b_) \
({ \
typeof(value_a_) value_a_tmp = (value_a_); \
typeof(value_b_) value_b_tmp = (value_b_); \
(value_a_tmp < value_b_tmp) ? value_a_tmp : value_b_tmp; \
})
Class: CORRECTNESS. Obligation: project requirement.
Keep feature selection explicit and bounded. Do not redefine C keywords, standard identifiers, or public functions as unrelated operations. Do not build include filenames from untrusted or implicit macro state. A macro that changes public layout or calling convention is an ABI input and must be included in the profile and compatibility tests. Generate only project-prefixed identifiers.
Noncompliant fragment (do not copy):
#define malloc(size_) MEM_malloc(size_) #define INCLUDE_FILE(name_) <name_> #include INCLUDE_FILE(config.h)
Contextual C example:
#if !defined(MEM_FEATURE_STATS) #define MEM_FEATURE_STATS ((int)(0)) #endif
Class: CORRECTNESS. Obligation: project requirement.
Name domain limits, timeouts, units, protocol masks, and repeated constants. Zero, one, and plainly explained representation operations may remain literals. Test vectors may state their concrete values directly. Do not create meaningless names such as VALUE_8 merely to avoid a literal; name the protocol width or quantity instead.
Contextual C example:
static const uint32_t g_retry_limit = 3u;
static const int32_t g_temperature_max_c = 85;
if (retry_count >= g_retry_limit)
EX_handleError();
if (temperature > g_temperature_max_c)
EX_shutdownOutput();
Noncompliant fragment (do not copy):
if (retry_count >= 3U)
{
EX_handleError();
}
if (temperature > 85)
{
EX_shutdownOutput();
}
Class: CORRECTNESS. Obligation: project requirement.
Use token pasting (##) only for controlled boilerplate generation. The ## operator concatenates preprocessor tokens. It does not create strings; it creates code tokens.
Contextual C example:
#define MAKE_VAR(name_) int module_##name_ MAKE_VAR(foo);
Contextual C example:
int module_foo;
Contextual C example:
#define APP_DECLARE_FLAG(name_, bit_) \
enum \
{ \
APP_FLAG_##name_ = (1U << (bit_)) \
}
APP_DECLARE_FLAG(READ, 0U);
APP_DECLARE_FLAG(WRITE, 1U);
Class: CORRECTNESS. Obligation: project requirement.
Do not pass assignments, increments, decrements, or state-changing calls as arguments to project function-like macros. Compute the value first. The standard assertion facility must likewise receive a side-effect-free expression. This restriction does not prohibit ordinary function calls with evaluated arguments; those remain subject to sequencing and order-of-evaluation rules.
Noncompliant fragment (do not copy):
result = MAX(value_a++, value_b); flags = SET_MASK(register_value, get_mask());
Contextual C example:
uint32_t mask = 0u; uint32_t value_a_tmp = 0u; value_a_tmp = value_a; mask = MASK_getCurrent(); result = UTIL_MAX(value_a_tmp, value_b); flags = REG_SET_MASK(register_value, mask);
Class: CORRECTNESS. Obligation: project requirement.
Qualify every shipped feature variant and document feature defaults. Dead branches are not validated by compiling a different variant.
Contextual C example:
#if defined(PLATFORM_HAS_DMA) ret = DMA_copy(dst, src, size_bytes); #else ret = CPU_copy(dst, src, size_bytes); #endif
Noncompliant fragment (do not copy):
#if defined(DEBUG) authorization_required = false; #endif
Class: CORRECTNESS. Obligation: project requirement.
Use explicit #if defined(NAME) tests for presence and #if !defined(NAME) for absence. Use numeric #if NAME only for a documented numeric feature macro. An #else is allowed for the exhaustively documented fallback. Unknown targets or missing mandatory capabilities must fail with a diagnostic, not silently select a permissive or ABI-incompatible implementation.
Source context: gcc-dialect.
Contextual C example:
#if defined(CONFIG_FEATURE_X) #define APP_FEATURE_X_ENABLED ((int)(1)) #elif !defined(CONFIG_FEATURE_X) #define APP_FEATURE_X_ENABLED ((int)(0)) #endif
Noncompliant fragment (do not copy):
#ifdef CONFIG_FEATURE_X int feature_value = 1; #else int feature_value = 0; #endif
Class: CORRECTNESS. Obligation: project requirement.
Do not silently redefine an existing macro. Use #undef only for a bounded, owned adaptation such as an X-macro pass, a test fixture, or foreign-header containment. Record why it is needed and where its effect ends. Do not use macro redefinition to change another module's API or implementation behavior.
Contextual C example:
#if !defined(APP_BUFFER_SIZE) #define APP_BUFFER_SIZE ((size_t)(256U)) #endif
Noncompliant fragment (do not copy):
#undef APP_BUFFER_SIZE #define APP_BUFFER_SIZE ((size_t)(256U))
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Keep compiler-specific attributes, builtins, and pragmas in named compiler or platform adapters. Require a tested fallback or an explicit unsupported-target error. ISO C23 typeof and typeof_unqual are language features; GNU statement expressions and older-dialect uses of compiler typeof spellings are extensions. The C17 compatibility profile cannot assume C23 syntax. A successful compiler flag probe does not certify support for every feature of that C edition.
Related controls: CSTYLE-026.
Source context: gcc-dialect.
Contextual C example:
#define MEM_ATTR_PRINTF__(fmt_idx_, arg_idx_) \
__attribute__((format(printf, fmt_idx_, arg_idx_)))
Noncompliant fragment (do not copy):
#define MEM_MAX(a_, b_) \
({ typeof(a_) a_tmp = (a_); typeof(b_) b_tmp = (b_); \
(a_tmp > b_tmp) ? a_tmp : b_tmp; })
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Use _Generic only in a project utility header to implement a documented type-safe adapter or compile-time dispatch. A generic selection must not hide business logic, runtime state changes, ownership transfer, allocation, or control-flow side effects.
Every association expression must satisfy the same public contract, and the controlling expression must not depend on evaluation for a side effect. Prefer a normal typed function when callers do not require compile-time type selection.
Contextual C example:
#define TYPE_WIDTH(x_) _Generic((x_), uint32_t: 32u, uint64_t: 64u)
Noncompliant fragment (do not copy):
#define PROCESS(x_) _Generic((x_), request_t: processRequest, response_t: processResponse)(x_) /* business dispatch hidden in macro */
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Inline assembly is prohibited in ordinary module logic. A reviewed platform, compiler, synchronization, or cryptographic adapter may use it only when a standard C construct, compiler intrinsic, or separately compiled assembly implementation cannot express the required semantic or measured behavior.
Every permitted block must document and encode:
volatile on an assembly statement does not describe a memory barrier or an unknown memory effect. Declare the exact compiler and machine contract. Common assembly fragments belong behind named helpers; Linux similarly recommends using inline assembly only when necessary and wrapping common fragments in helpers.linux-coding-style
Contextual C example:
ret = PLATFORM_crc32(input, size_bytes, &crc);
Noncompliant fragment (do not copy):
crc = __builtin_ia32_crc32si(crc, value); /* ISA intrinsic leaked into portable core */
Class: CORRECTNESS. Obligation: project requirement.
Describe operations, side effects, failures, and ownership before selecting their control-flow shape.
Failure scenarios: CPIT-034, CPIT-043, CPIT-105.
Contextual C example:
int MODULE_run(module_t *module)
{
int ret = EXIT_SUCCESS;
if (module == (module_t *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
function_output:
return ret;
}
Noncompliant fragment (do not copy):
int MODULE_run(module_t *module)
{
if (module == NULL) return -1;
if (!module->ready) return -2;
return do_work(module);
}
Class: PROJECT_STYLE. Obligation: review trigger.
Keep each function responsible for one operation and its failure handling. Split a function when independent responsibilities obscure ownership or state transitions. Do not split solely to satisfy a line-count metric if doing so hides an invariant. A public operation must describe its preconditions, postconditions, side effects, and failure-state guarantee.
Failure scenarios: CPIT-034, CPIT-045.
Layout example (not executable):
parse_header() parse_payload() validate_crc() PROCESS_frame() composes the three focused steps
Noncompliant fragment (do not copy):
Layout, diagnostic, or contract example. This block is not executable C.
PROCESS_frame() is 600 lines and parses, validates, allocates, logs, retries, and writes storage
Class: ANALYZABILITY. Obligation: review trigger.
Use cyclomatic complexity 10 as a review trigger for production functions. Record the tool and counting convention. A result above the threshold requires review, not an automatic claim that the function is unsafe. Generated code and bounded host tests may use a documented profile exception. Code metrics cannot replace tests or ownership analysis.
Contextual example:
Small function definition with <errno.h>, <stdlib.h> and its own declaring header. Complexity thresholds are review triggers, not a mathematical proof that the function is correct.
int SAMPLE_validatePair(int left, int right)
{
int ret = EXIT_SUCCESS;
if ((left < 0) || (right < 0))
{
ret = -EINVAL;
goto function_output;
}
function_output:
return ret;
}
Class: ANALYZABILITY. Obligation: review trigger.
Use cognitive complexity 15 as an inherited review trigger only when the selected analyzer defines and reports that metric. Record its version and configuration. Do not equate a score with human comprehension or correctness. Prefer eliminating hidden state and unnecessary nesting over metric-driven refactoring that merely moves complexity to callees.
Contextual C example:
#define EX_ARRAY_MIN ((int)(0U))
#define EX_ARRAY_MAX ((int)(100U))
int EX_complexFunction(int array[], size_t size, int flag)
{
int ret = EXIT_SUCCESS;
size_t index_i = 0u;
size_t index_j = 0u;
if (array == (int *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
for (index_i = 0u; index_i < size; index_i++)
{
if (array[index_i] < EX_ARRAY_MIN)
array[index_i] = EX_ARRAY_MIN;
else if (flag != 0)
{
for (index_j = 0u; index_j < size; index_j++)
{
if ((index_i != index_j) &&
(array[index_j] > EX_ARRAY_MAX))
{
array[index_i] = EX_ARRAY_MAX;
}
}
}
}
function_output:
return ret;
}
Class: PROJECT_STYLE. Obligation: review trigger.
Prefer no more than 5 parameters.
Contextual C example:
int EX_calculateSum(int value_a, int value_b, int value_c);
Noncompliant fragment (do not copy):
int EX_processData(int value_a,
int value_b,
int value_c,
int value_d,
int value_e,
int value_f);
Class: CORRECTNESS. Obligation: project requirement.
Validate nullability, sizes, ranges, and domain constraints required by each API. Zero length is not universally invalid: document empty-buffer behavior. A NULL check cannot prove lifetime, alignment, capacity, or provenance; those are caller obligations unless a validated handle system enforces them. Never dereference an output-handle pointer before checking the pointer itself. If the function reads *out, its contract must require initialized storage.
Failure scenarios: CPIT-011, CPIT-055, CPIT-057, CPIT-083, CPIT-090.
Complete example: worked sources.
Contextual C example:
int EX_processItem(int *item, size_t size)
{
int ret = EXIT_SUCCESS;
if (item == (int *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
if (size == 0u)
{
ret = -EINVAL;
goto function_output;
}
function_output:
return ret;
}
Class: CORRECTNESS. Obligation: project requirement.
Argument validation checks whether an API contract was respected. Untrusted input validation checks whether data from outside the trust boundary is safe to use. Any value from file, network, IPC, environment variables, command line, persistent storage, fuzzers, firmware blobs, corrupted metadata, or external modules is untrusted. Validate untrusted values before:
Failure scenarios: CPIT-042, CPIT-055, CPIT-067, CPIT-083, CPIT-089, CPIT-091, CPIT-092, CPIT-093, CPIT-094, CPIT-101, CPIT-102, CPIT-104.
Contextual C example:
if (payload_size > MEM_PAYLOAD_MAX)
{
ret = -EINVAL;
goto function_output;
}
Class: CORRECTNESS. Obligation: project requirement.
Validate integer input against the actual allowed enum members before conversion. A range check suffices only for a documented contiguous domain. Reject sentinel values, unknown flag bits, and reserved protocol values. An enum object can carry values outside the intended business domain; its C type is not an input-validation mechanism.
Failure scenarios: CPIT-046, CPIT-054.
Noncompliant fragment (do not copy):
state = (mem_state_t)raw_value; table[state]();
Contextual C example:
if ((raw_value < 0) || (raw_value >= (int)MEM_STATE_MAX))
{
ret = -EINVAL;
goto function_output;
}
state = (mem_state_t)raw_value;
Class: CORRECTNESS. Obligation: project requirement.
Keep assignments, increments, and state-changing calls out of if and loop conditions. Pure predicates are allowed when their contract has no observable mutation. The initialization and iteration clauses of for may assign and advance an index declared at function entry; they must not declare a new one. Short-circuit guards may protect later reads. Do not separate a check and use in a way that creates a concurrent race.
Failure scenarios: CPIT-034, CPIT-035.
Noncompliant fragment (do not copy):
if ((ret = FILE_read(buffer, size)) != EXIT_SUCCESS)
{
goto function_output;
}
while (index++ < size)
{
EX_doSomething();
}
Contextual C example:
ret = FILE_read(buffer, size);
if (ret != EXIT_SUCCESS)
goto function_output;
while (index < size)
{
EX_doSomething();
index++;
}
Class: CORRECTNESS. Obligation: project requirement.
Use const on input parameters whenever the function does not modify the provided data.
Contextual C example:
int FILE_writeBuffer(const uint8_t buffer[], size_t size); int JSON_parse(const char input[], json_object_t *out);
Class: CORRECTNESS. Obligation: project requirement.
A writable variable-length output needs a pointer and a declared capacity, passed as parameters or as a specified span. Define bytes versus elements, written versus required length, termination, overlap, and failure behavior. Check integer ranges before forming destination pointers. An output pointer to one typed scalar or a fixed-layout DTO does not need a redundant byte capacity. A documented size-zero/NULL no-op must avoid even zero-length libc calls with invalid pointers.
Failure scenarios: CPIT-013, CPIT-029.
Complete example: worked sources.
Contextual C example:
int PATH_build(char path[], size_t path_size); int FRAME_encode(uint8_t buffer[], size_t buffer_size);
Noncompliant fragment (do not copy):
int PATH_build(char path[]); int FRAME_encode(uint8_t buffer[]);
Class: CORRECTNESS / ANALYZABILITY / PROJECT_STYLE. Obligation: project requirement.
Fallible project operations normally return int, with zero for success and a documented negative errno-style error domain. Use out parameters for results. Declare ret first, initialize it to the success value, and return it only at the final function_output label. Validation failures set ret and jump to that label. Guard returns and other early returns are forbidden, including before resource acquisition.
Use the same exit for cleanup. Initialize every resource variable before validation so cleanup can distinguish acquired resources from empty handles. Release only acquired resources and preserve the primary failure if cleanup also fails. Do not declare cleanup variables after the label.
Callbacks, interrupt handlers, and infallible accessors or predicates retain the return type required by their contract. Value-returning functions use a ret variable of that type and the same single normal exit. A void function ends with one return; under function_output; it does not need a fictitious status. The return-type exception does not authorize early returns or hidden failures. A function without another jump uses an explicit final goto function_output so the common label is used. Fatal assertions in the declared host-test/debug profile are not normal returns and are not a recoverable error mechanism.
Source context: linux-style.
Complete example: worked sources.
Contextual example:
Function definition. Include <stddef.h>, <errno.h> and <stdlib.h>; declare the public function in its own header. A nonzero count is the complete input contract.
int SAMPLE_validateCount(size_t count)
{
int ret = EXIT_SUCCESS;
if (count == 0u)
{
ret = -EINVAL;
goto function_output;
}
function_output:
return ret;
}
Class: CORRECTNESS. Obligation: project requirement.
Give every error value a documented meaning and scope. Negative POSIX-style names may be used in a POSIX adapter, but do not assume their numeric values are a portable serialized or cross-platform contract. The example uses its own fixed negative status values. Map foreign errors once at an adapter boundary. Do not use global errno as the implicit error channel of a reusable project API.
Complete example: worked sources.
Contextual C example:
typedef enum NetRet
{
NET_RET_SUCCESS = (int)(EXIT_SUCCESS),
NET_RET_INVALID_ARG = (int)(-EINVAL),
NET_RET_IO = (int)(-EIO),
NET_RET_BACKEND_FAILED = (int)(-EFAULT)
} net_ret_t;
Class: CORRECTNESS. Obligation: project requirement.
Check fallible results before using outputs or committing state. Preserve the primary operation error when cleanup also fails; retain the cleanup error in diagnostics when needed. Define partial-write and retry behavior explicitly. Ignoring a result requires a stated reason, such as best-effort diagnostics on an already fatal host-test path. Never discard a security decision's result.
Failure scenarios: CPIT-055, CPIT-068, CPIT-083, CPIT-087.
Source context: linux-style.
Complete example: worked sources.
Contextual C example:
ret = NETWORK_sendPacket(packet);
if (ret != EXIT_SUCCESS)
goto function_output;
Noncompliant fragment (do not copy):
NETWORK_sendPacket(packet);
Class: SECURITY. Obligation: project requirement.
Use runtime validation for external input and recoverable operational failures. Assertions document internal invariants and must have no side effects; they may be removed by a release build. A library must not terminate the process unless its documented fatal policy explicitly permits it. Logs must preserve useful error identity without exposing secrets, uninitialized bytes, or private addresses. Host-test termination is a separate, explicit test profile.
Failure scenarios: CPIT-093, CPIT-097, CPIT-105, CPIT-119.
Source context: logging.
Contextual C example:
assert(buffer != (uint8_t *)(NULL));
ret = STORAGE_read(block_id, data);
if (ret != EXIT_SUCCESS)
{
LOG_ERROR("STORAGE_read failed: block_id=%u ret=%d", block_id, ret);
goto function_output;
}
Noncompliant fragment (do not copy):
assert(STORAGE_read(block_id, data) == EXIT_SUCCESS);
Class: SECURITY. Obligation: project requirement.
Keep format strings trusted and match every variadic argument to its required type. Use the standard integer format macros where appropriate and zu for size_t. For bounded formatting, handle negative status separately from output that would not fit. A size parameter does not guarantee a complete result. Configure compiler format checking for wrappers when the toolchain supports it.
Failure scenarios: CPIT-055, CPIT-061, CPIT-062, CPIT-093, CPIT-095.
Source context: logging.
Noncompliant fragment (do not copy):
printf(user_input); MEM_log(level, user_input);
Contextual C example:
if (user_input == (const char *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
ret = MEM_log(level, "%s", user_input);
if (ret != EXIT_SUCCESS)
goto function_output;
Contextual C example:
MEM_ATTR_PRINTF__(2, 3) int MEM_log(mem_log_level_t level, const char format[], ...);
Class: ANALYZABILITY. Obligation: project requirement.
Write a control in terms a reviewer or tool can evaluate: scope, precondition, required action, and failure outcome. Identify checks that need human reasoning. A token search is evidence only for the syntax it recognizes; it is not proof of ownership, authorization, lifetime, or race freedom. Record what the test or analyzer exercised instead of marking all related controls verified.
Failure scenarios: CPIT-030.
Noncompliant fragment (do not copy):
Layout, diagnostic, or contract example. This block is not executable C.
Use good judgment with pointers.
Layout example (not executable):
Every public function that writes to a caller-provided buffer shall receive a non-NULL buffer pointer and a size parameter.
Class: CORRECTNESS. Obligation: project requirement.
A module-specific status typedef includes ret in its name and keeps the zero-success, negative-error convention. Its implementation declares ret of that type first and returns it through function_output.
Callbacks, interrupt handlers, and infallible accessors or predicates may use the exact return type required by their contract under CSTYLE-064. This changes the result type, not the single-exit discipline. Do not cast a function pointer to evade signature compatibility.
Contextual C example:
typedef enum FileOpRet
{
FILE_OP_RET_SUCCESS = (int)(EXIT_SUCCESS),
FILE_OP_RET_INVALID_PATH = (int)(-EINVAL),
FILE_OP_RET_IO_ERROR = (int)(-EIO)
} file_op_ret_t;
file_op_ret_t FILE_openFile(const char path[])
{
file_op_ret_t ret = FILE_OP_RET_SUCCESS;
if (path == (const char *)(NULL))
{
ret = FILE_OP_RET_INVALID_PATH;
goto function_output;
}
function_output:
return ret;
}
Class: ARCHITECTURE / CORRECTNESS. Obligation: project requirement.
A callback contract specifies its exact signature, context owner, invocation thread, lifetime, nullability, borrowed arguments, output capacities, allocation, blocking, reentrancy, errors, partial side effects, cancellation, and teardown. The table may be copied while its context remains borrowed. Unbinding does not release context until new invocations are excluded and in-flight calls finish. Runtime replacement requires synchronization. Do not hold an internal lock across unknown callback code without a reviewed locking contract.
Failure scenarios: CPIT-026, CPIT-032.
Contextual C example:
typedef int (*send_cb_t)(void *context, const uint8_t *data, size_t size_bytes); /* Contract documents ownership, blocking, and reentrancy. */
Noncompliant fragment (do not copy):
typedef void (*cb_t)(); /* argument types and error contract unspecified */
Class: PROJECT_STYLE. Obligation: project requirement.
To reduce cognitive complexity, simplify boolean conditions whenever doing so improves clarity.
Contextual C example:
if ((!is_ready) || (!is_valid))
EX_handleError();
if (flag)
EX_doSomething();
if (is_enabled && (has_input || has_backup_input))
EX_doSomething();
Class: PROJECT_STYLE. Obligation: project requirement.
Prefer boolean names that describe the active or allowed condition directly.
Contextual example:
Function-body fragment. ret is declared first, is_running at entry. The injected step callback must obey the execution budget and eventually clear is_running or fail; the name alone does not establish progress.
bool is_running = false;
/* After validating the operation and its bounded execution budget. */
is_running = true;
while (is_running)
{
ret = step(step_context, &is_running);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: CORRECTNESS / ANALYZABILITY / PROJECT_STYLE. Obligation: project requirement.
Do not use break or continue to alter iteration control. Express normal termination and iteration selection through the loop condition and explicit state. Declare loop variables at function entry. A failure may jump forward to function_output, which remains the function's only normal return path. break is permitted to terminate a switch case; that is not an exception for breaking out of an enclosing loop.
Every finite operation needs a bound or a progress argument. A service loop may run indefinitely only with a documented shutdown and scheduling policy. Safety-critical and externally driven loops need work/time budgets and a defined response when the budget is exhausted. Recursion requires an applicable profile and a justified maximum depth; it is forbidden in the hard-real-time profile.
Related controls: CSTYLE-075.
Failure scenarios: CPIT-016, CPIT-034, CPIT-046, CPIT-068, CPIT-083.
Contextual example:
Function-body fragment. All declarations are at function entry; matches is an injected infallible predicate. The loop uses its condition, not break or continue, to stop.
size_t index = 0u;
bool keep_searching = false;
/* After validating items, size, and the required predicate callback. */
keep_searching = true;
for (index = 0u; (index < item_count) && keep_searching; index++)
{
keep_searching = !matches(match_context, &items[index]);
}
Class: CORRECTNESS. Obligation: project requirement.
Handle every valid state and reject invalid states. Use a default for untrusted or extensible inputs; enable an enum-exhaustiveness diagnostic as well where supported. Each nonempty case terminates explicitly unless deliberate fallthrough is documented with the selected dialect's supported annotation. Do not use default to hide newly added enum states from review.
Contextual C example:
switch (state)
{
case STATE_IDLE:
break;
case STATE_RUNNING:
break;
default:
ret = -EINVAL;
goto function_output;
}
Noncompliant fragment (do not copy):
switch (state)
{
case STATE_IDLE:
EX_prepareState();
case STATE_RUNNING:
EX_runState();
break;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Function arguments must not depend on their evaluation order. A function call must not modify an object in one argument and read or modify the same object in another argument.
Prefer separate statements whose order is visible:
Noncompliant fragment (do not copy):
EX_useValues(index++, index); EX_processItems(items[index++], items[index]);
Contextual C example:
size_t current_index = 0u; current_index = index; index++; EX_useValues(current_index, index);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Every out-parameter contract must state whether the function defines the output on every return or only on success. Unless an API requires another sentinel, initialize pointer outputs to typed NULL immediately after validating the out-parameter itself.
Avoid an output whose value after failure is unspecified:
Contextual C example:
int ITEM_create(item_t **item_out)
{
int ret = EXIT_SUCCESS;
item_t *item = (item_t *)(NULL);
if (item_out == (item_t **)(NULL))
{
ret = -EINVAL;
goto function_output;
}
*item_out = (item_t *)(NULL);
item = (item_t *)malloc(sizeof(*item));
if (item == (item_t *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
*item = (item_t){ 0 };
*item_out = item;
item = (item_t *)(NULL);
function_output:
free(item);
return ret;
}
Noncompliant fragment (do not copy):
int ITEM_find(item_t **item_out, item_t *item, bool is_found)
{
int ret = EXIT_SUCCESS;
if (item_out == (item_t **)(NULL))
{
ret = -EINVAL;
goto function_output;
}
if (is_found)
{
*item_out = item;
}
else
{
ret = -EINVAL;
}
function_output:
return ret;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A parameter that represents the first element of an array must use array notation. Use pointer notation for a pointer to one object, an optional object, an opaque handle, or another contract that is not an array.
Avoid hiding an array contract behind pointer notation:
In a function parameter, type array[] still adjusts to a pointer type. Array notation communicates intent but does not carry capacity; the function must also receive the element count, byte size, or an explicitly sized array type.
Contextual C example:
int EX_sumValues(const int values[], size_t value_count); int EX_updateValue(int *value);
Noncompliant fragment (do not copy):
int EX_sumValues(const int *values, size_t value_count);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Variadic functions are prohibited in ordinary module APIs. A controlled formatting, logging, tracing, or foreign-interface adapter may use ... when a fixed typed API cannot express the required contract.
An approved variadic function must:
Prefer a small wrapper around a typed va_list adapter:
Do not use ... as a general optional-argument or type-dispatch mechanism.
Contextual C example:
MEM_ATTR_PRINTF__(2, 3)
int MEM_log(mem_log_level_t level, const char format[], ...)
{
int ret = EXIT_SUCCESS;
va_list args;
if (format == (const char *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
va_start(args, format);
ret = MEM_logV(level, format, args);
va_end(args);
function_output:
return ret;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
The conditional operator may select a value. Its condition and result operands must have no side effects, and neither result operand may contain another conditional operator.
Prefer a compact value selection:
Use an if statement when either path performs work:
Contextual C example:
maximum = (value_a > value_b) ? value_a : value_b;
Contextual C example:
result = is_ready ? EX_processItem(item)
: use_backup ? EX_processBackup(item)
: -EINVAL;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
The comma operator is prohibited, including in a for iteration expression. This rule does not prohibit commas that separate function arguments, declarations, initialization elements, or enum constants.
Use separate statements and one explicit loop-control variable.
Noncompliant fragment (do not copy):
value = (EX_prepare(), EX_readValue());
for (index = 0u; index < count; index++, output_index++)
{
output[output_index] = input[index];
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Read errno only after an API reports failure through its documented return value. Capture it immediately, before logging, cleanup, allocation, or another library call can change it.
Rules:
Contextual C example:
FILE *file = (FILE *)(NULL);
int saved_errno = 0;
file = fopen(path, "rb");
if (file == (FILE *)(NULL))
{
saved_errno = errno;
ret = ERRNO_toFileRet(saved_errno);
goto function_output;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
A function name and return type must express the same semantic category.
Do not name a fallible action as if it were a query or return an error code from a name that callers naturally use as a condition.
Contextual C example:
int DEVICE_start(device_t *device); bool DEVICE_isReady(const device_t *device);
Noncompliant fragment (do not copy):
bool DEVICE_start(device_t *device); int DEVICE_isReady(const device_t *device);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Validate a function or callback pointer before invocation. Prefer validating all mandatory callbacks once at create or bind time, then record the invariant that a successfully bound object contains valid mandatory operations.
At a nullable invocation boundary, name and validate the callback explicitly:
The callback contract must also satisfy CSTYLE-071 and the lifetime, reentrancy, blocking, ownership, and error rules of the owning port.
Contextual C example:
send_cb_t send = (send_cb_t)(NULL);
if (callbacks == (const callbacks_t *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
send = callbacks->send;
if (send == (send_cb_t)(NULL))
{
ret = -EINVAL;
goto function_output;
}
ret = send(callbacks->context, data, data_size);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Recursion is prohibited by default in production code. An approved deviation must prove and document:
Use an explicit bounded worklist or loop when it makes stack and progress state visible. Tests and host tools may use recursion only under the same resource budget discipline.
Contextual C example:
while (node != (node_t *)(NULL))
{
node = node->next;
}
Noncompliant fragment (do not copy):
int walk(node_t *node)
{
return node == NULL ? 0 : walk(node->next); /* no static depth bound */
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
setjmp and longjmp are prohibited in ordinary project code. They bypass visible cleanup, ownership transfer, SESE, local-lifetime reasoning, and normal error propagation.
An external dependency that requires nonlocal control flow must be isolated in an adapter. The adapter must not jump across a project-owned frame and must translate control back into the module error domain before returning.
Contextual C example:
ret = operation();
if (ret != EXIT_SUCCESS)
goto function_output;
Noncompliant fragment (do not copy):
if (setjmp(env) == 0)
{
run();
}
/* longjmp may bypass cleanup */
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A compiler assumption, unreachable marker, or equivalent portability macro may encode only a previously proved internal invariant. It must not:
LLVM distinguishes unreachable internal bugs from conditions caused by user input, which require recoverable error handling.llvm-coding-standards
Contextual C example:
if (state >= STATE_MAX)
{
ret = -EINVAL;
goto function_output;
}
PROJECT_ASSUME__(state < STATE_MAX);
Noncompliant fragment (do not copy):
if (state >= STATE_MAX)
{
__builtin_unreachable(); /* state came from the network */
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Mark a result with the project compiler adapter's must-check annotation when silently ignoring it can lose ownership, integrity, authentication, persistence, or an essential state transition.
Typical candidates include allocation, persistent writes, transaction commits, security checks, firmware update operations, fallible lock acquisition, and resource transfer. Do not annotate every integer-returning function; the marker must communicate a material obligation.
The annotation supplements normal review and error propagation. A cast to void must not silence a must-check result without an approved, documented reason.
Contextual C example:
APP_MUST_CHECK__ int STORAGE_commit(storage_t *storage);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
An I/O call that accepts a byte count must have an explicit completion contract. Code must distinguish full progress, partial progress, end of input, temporary unavailability, interruption before progress, permanent failure, and cancellation or deadline expiry when those outcomes exist.
Rules:
POSIX explicitly permits partial writes and defines interruption behavior that can return either transferred bytes or EINTR before progress.posix-write posix-read
Contextual example:
Entry-declared counters and ret; caller provides requested_bytes writable storage. The injected read_part retries EINTR according to a bounded deadline and never writes past its supplied capacity. completed_bytes remains available to report partial progress on error.
while (completed_bytes < requested_bytes)
{
ret = read_part(io_context, buffer + completed_bytes,
requested_bytes - completed_bytes, &received_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
if (received_bytes == 0u)
{
ret = -EIO;
goto function_output;
}
if (received_bytes > requested_bytes - completed_bytes)
{
ret = -EOVERFLOW;
goto function_output;
}
completed_bytes += received_bytes;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Elapsed-time measurement, retry budgets, leases, watchdog windows, and relative deadlines must use a project monotonic-clock abstraction. Calendar time may be used for timestamps and externally specified civil-time events, but must not be subtracted to enforce a duration.
The time contract must state units, resolution, wrap behavior, maximum interval, comparison method, and whether suspend time is included. Deadline arithmetic must use checked or wrap-safe helpers for the represented clock domain. Do not mix values from wall-clock, monotonic, CPU-time, device, or simulation clocks.
POSIX defines the monotonic clock so clock setting cannot move its origin and notes that interval measurements using it are not affected by wall-clock updates.posix-monotonic-clock
Contextual example:
Both timestamps come from the same monotonic epoch and unit, with a no-wrap interval contract. Variables are entry declarations. Wall-clock timestamps are a different type/domain in the surrounding API.
ret = monotonic_now(clock_context, &now_ns);
if (ret != EXIT_SUCCESS)
goto function_output;
if (now_ns < start_ns)
{
ret = -ERANGE;
goto function_output;
}
elapsed_ns = now_ns - start_ns;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A platform profile that exposes file descriptors, sockets, pipes, process handles, or equivalent kernel resources must define one owner, one close path, and one inheritance policy for each handle. A handle intended only for the current process must receive its close-on-exec or non-inheritable property in the same operation that creates the handle when the platform provides an atomic creation flag.
On Linux and POSIX profiles, use O_CLOEXEC, SOCK_CLOEXEC, pipe2() or the corresponding creation-time mechanism instead of a later fcntl() step when a concurrent fork() and execve() can occur. Linux documents the race created by setting FD_CLOEXEC in a separate operation.linux-open-cloexec
A platform adapter may use the native API:
Noncompliant creation sequence:
The second sequence exposes a window in which another thread can fork and exec with the descriptor still inheritable.
Contextual example:
Linux platform-adapter function: include <fcntl.h>, <errno.h>, <stdlib.h> and the owning internal header. PLATFORM_errorFromErrno must return a nonzero project error for this failure. Success transfers the descriptor to the caller; no later operation in this function can fail. On error, fd_out is unchanged. No zero-valued descriptor is closed during failed validation.
static int platform_openConfig(const char *path, int *fd_out)
{
int ret = EXIT_SUCCESS;
int fd = 0;
if ((path == (const char *)(NULL)) || (fd_out == (int *)(NULL)))
{
ret = -EINVAL;
goto function_output;
}
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
{
ret = PLATFORM_errorFromErrno(errno);
goto function_output;
}
*fd_out = fd;
function_output:
return ret;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A persistent state transition that spans more than one storage write must define its atomicity, durability, and recovery protocol. The owner must account for power loss, reset, short writes, reordered writes, failed flushes, and torn storage units supported by the medium.
The protocol must identify the commit point and recovery rule. Approved designs may use A/B slots, a journal, write-ahead logging, copy-on-write state, a commit marker, or another mechanism with equivalent evidence. SQLite tests atomic commit by injecting incomplete, reordered, and corrupted writes around simulated power loss.sqlite-atomic-commit
Compliant transaction shape:
Noncompliant in-place update:
A reset between those writes can expose a state that never existed as a valid configuration.
Contextual C example:
int CONFIG_commit(const config_image_t *image)
{
int ret = EXIT_SUCCESS;
uint32_t generation = 0u;
if (image == (const config_image_t *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
ret = STORAGE_nextGeneration(&generation);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = STORAGE_writeStagingImage(image, generation);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = STORAGE_flushStagingImage();
if (ret != EXIT_SUCCESS)
goto function_output;
ret = STORAGE_writeCommitRecord(generation);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = STORAGE_flushCommitRecord();
function_output:
return ret;
}
Noncompliant fragment (do not copy):
ret = STORAGE_writeField(
CONFIG_TIMEOUT_OFFSET,
&timeout_ms,
sizeof(timeout_ms)
);
if (ret != EXIT_SUCCESS)
{
goto function_output;
}
ret = STORAGE_writeField(CONFIG_MODE_OFFSET, &mode, sizeof(mode));
function_output:
return ret;
Class: CORRECTNESS. Obligation: project requirement.
Apply allocation, bounds, lifetime, and ownership controls as one contract; none substitutes for the others.
Complete example: worked sources.
Contextual C example:
buffer = (uint8_t *)malloc(size_bytes);
if (buffer == (uint8_t *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
/* owner and cleanup path are explicit */
Noncompliant fragment (do not copy):
buffer = (uint8_t *)malloc(size_bytes); buffer[0] = 0u; /* allocation and ownership unchecked */
Class: CORRECTNESS. Obligation: project requirement.
Check every allocation result and establish exactly one ownership protocol. State whether allocation is permitted, which family supplies it, what budget applies, and whether failure leaves prior state unchanged. Initialization paths must unwind partially acquired resources. calloc supplies zero bits, not a portable constructor for every pointer, floating value, or resource handle. Use semantic initialization for such members.
Failure scenarios: CPIT-004, CPIT-007.
Source context: c23.
Complete example: worked sources.
Contextual C example:
int *buffer = (int *)(NULL);
size_t alloc_size = 0u;
bool has_overflow = false;
has_overflow = ARITH_mulSize(count, sizeof(*buffer), &alloc_size);
if (has_overflow)
{
ret = -ENOMEM;
goto function_output;
}
buffer = (int *)malloc(alloc_size);
if (buffer == (int *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
Class: PROJECT_STYLE / PORTABILITY / CORRECTNESS. Obligation: project requirement.
When a function returns void *, cast the result explicitly to the destination pointer type. This applies to allocation functions and injected allocator callbacks. Conversions from an opaque void * context to its concrete object-pointer type must also be explicit and remain inside the adapter or callback implementation that owns the context contract.
For every explicit NULL initializer, assignment, comparison, argument, or pointer result, use the corresponding pointer cast, such as (buffer_t *)(NULL) or (const uint8_t *)(NULL). A null callback uses its function-pointer typedef. Aggregate zero initialization under CSTYLE-107 does not need one literal NULL per member.
These are mandatory project conventions. The cast does not establish alignment, lifetime, ownership, or allocation size. Include the correct function prototype; never use a cast to hide a diagnostic. T ** is not interchangeable with void **, and object-pointer casts do not permit function-pointer conversions.
Source context: c23.
Complete example: worked sources.
Contextual example:
Function-body fragment. ret is declared first; declarations shown belong at function entry. allocation_bytes is a validated nonzero allocation size. The owner releases buffer on every required exit path; this fragment only illustrates the required conversion.
int *buffer = (int *)(NULL);
size_t allocation_bytes = 0u;
/* After argument validation and checked size calculation. */
buffer = (int *)malloc(allocation_bytes);
if (buffer == (int *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
Class: CORRECTNESS. Obligation: project requirement.
Derive allocation sizes with checked arithmetic before calling the allocator. Use sizeof(*pointer) for the object or element, and include header, padding, alignment, and terminator costs where applicable. Apply the product's budget after representability checks. Specify zero-count behavior. A mathematically representable allocation can still be unaffordable or violate a real-time bound.
Related controls: CSTYLE-052.
Source context: c23.
Complete example: worked sources.
Contextual C example:
item_t *ptr = (item_t *)(NULL);
size_t alloc_size = 0u;
bool has_overflow = false;
has_overflow = ARITH_mulSize(count, sizeof(*ptr), &alloc_size);
if (has_overflow)
{
ret = -ENOMEM;
goto function_output;
}
ptr = (item_t *)malloc(alloc_size);
if (ptr == (item_t *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
Noncompliant fragment (do not copy):
ptr = malloc(sizeof(int) * count);
Class: CORRECTNESS. Obligation: project requirement.
Handle zero size before any realloc call: either reject it or explicitly free and reset the owner, as the API contract specifies. For positive sizes, store the result in a temporary and update ownership only on success. Failure preserves the old allocation under the allocator contract. After success, use only the returned base and newly derived aliases, even when its numeric address matches the old one. Update size/capacity metadata only with the successful ownership transition. The example fault-injects this path.
Failure scenarios: CPIT-008.
Source context: c23.
Complete example: worked sources.
Contextual example:
Function-body fragment. ret, buffer, replacement and allocation_bytes are declared at entry; buffer already holds the owning base pointer after validation. checked_size is an approved checked-multiplication callback. The zero-size branch intentionally implements release; a different API may reject zero before calling realloc. On realloc failure the old allocation remains owned; successful relocation invalidates prior aliases.
int *replacement = (int *)(NULL);
size_t allocation_bytes = 0u;
/* After validating ownership and new_count. */
if (new_count == 0u)
{
free(buffer);
buffer = (int *)(NULL);
goto function_output;
}
ret = checked_size(checked_context, new_count, sizeof(*buffer),
&allocation_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
replacement = (int *)realloc(buffer, allocation_bytes);
if (replacement == (int *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
buffer = replacement;
Class: CORRECTNESS. Obligation: project requirement.
Document allocation performed by an operation and by any callback it invokes. Caller-provided result storage is preferred where it makes budgets predictable. An out parameter does not prove that a parser or callback makes no allocations. A no-allocation profile must inspect the transitive call path and measure or instrument the implementation; a function name or signature is insufficient.
Failure scenarios: CPIT-083, CPIT-093.
Complete example: worked sources.
Contextual C example:
int JSON_parse(const char input[], json_object_t *out);
Noncompliant fragment (do not copy):
json_object_t *JSON_parse(const char input[]);
Class: ARCHITECTURE / CORRECTNESS. Obligation: project requirement.
Document the owner, allocator family, release authority, validity interval, nullability, and aliasing rules of every exposed pointer. Distinguish borrowing from transfer. A copied pointer is not a copied object or an ownership transfer. Refcount, arena, pool, and GC lifetimes require their own protocols. Clearing one released handle is useful hygiene but does not invalidate or repair other aliases. Moveable objects need registered references or a supported pinning contract.
Failure scenarios: CPIT-002, CPIT-003, CPIT-005, CPIT-009, CPIT-031.
Complete example: worked sources.
Contextual C example:
/* * On success, the caller owns *buffer_out and must free it. */ int UTIL_createBuffer(size_t size, char **buffer_out); /* * The buffer is owned by the module and must not be freed. */ const char *CONFIG_getPath(void);
Class: ARCHITECTURE / CORRECTNESS. Obligation: project requirement.
Let the operation owner supply result DTOs and buffers when that makes capacity and lifetime explicit. Do not force every internal temporary into the highest caller; keep transient working state near its use. Publicly shareable DTO layout is an intentional value contract, not permission to expose or embed a peer module's private context. Distinguish in-process and wire DTOs.
Complete example: worked sources.
Contextual C example:
reply_t reply = { 0 };
ret = SERVICE_call(request, &reply);
Noncompliant fragment (do not copy):
reply_t *reply = SERVICE_call(request); /* ownership/allocation hidden */
Class: CORRECTNESS. Obligation: project requirement.
Keep automatic objects within their lifetime and prevent references to them from escaping that interval. A heap object may borrow an automatic object only when its use ends before that object's lifetime ends and the contract permits it. For longer retention, copy the data or retain a separately owned object.
Automatic variables are declared at function entry under CSTYLE-107. Narrow resource use through explicit ownership and smaller functions, not declarations inside a nested block or loop. Initialize every cleanup-owned resource before validation and never read an object whose initialization could be bypassed.
Failure scenarios: CPIT-001, CPIT-033.
Source context: c23.
Complete example: worked sources.
Noncompliant fragment (do not copy):
char *UTIL_getBuffer(void)
{
char *ret = (char *)(NULL);
char buffer[128] = { 0 };
ret = buffer;
function_output:
return ret;
}
Contextual C example:
int UTIL_getBuffer(char buffer[], size_t size);
Contextual C example:
int UTIL_getBuffer(char **buffer_out);
Noncompliant fragment (do not copy):
int EX_badStoreLocal(context_t *context)
{
int ret = EXIT_SUCCESS;
callback_data_t callback_data = { 0 };
if (context != (context_t *)(NULL))
{
context->callback_data = &callback_data;
}
function_output:
return ret;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Each object must be released by the allocator family that created it. The ownership contract must identify the matching release function when an API does not use the standard malloc() and free() pair.
Prefer matching pairs:
Do not pass stack objects, static objects, interior pointers, or foreign allocator blocks to a release function.
Noncompliant fragment (do not copy):
buffer = (uint8_t *)malloc(buffer_size);
if (buffer == (uint8_t *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
MEM_free(buffer);
Contextual C example:
buffer = (uint8_t *)MEM_alloc(buffer_size);
if (buffer == (uint8_t *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
MEM_free(buffer);
buffer = (uint8_t *)(NULL);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
An API that takes ownership must state the exact transfer point, including what happens on failure. After a successful transfer, the caller must not read, write, release, or derive another pointer from the transferred object.
Finish caller-owned work before the transfer and clear the caller's pointer after success:
Noncompliant fragment (do not copy):
if ((queue == (queue_t *)(NULL)) ||
(item == (item_t *)(NULL)))
{
ret = -EINVAL;
goto function_output;
}
ret = QUEUE_push(queue, item);
if (ret != EXIT_SUCCESS)
{
goto function_output;
}
item->state = ITEM_STATE_READY;
Contextual C example:
if ((queue == (queue_t *)(NULL)) || (item == (item_t *)(NULL)))
{
ret = -EINVAL;
goto function_output;
}
item->state = ITEM_STATE_READY;
ret = QUEUE_push(queue, item);
if (ret != EXIT_SUCCESS)
goto function_output;
item = (item_t *)(NULL);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Every acquired resource must have one visible, deterministic release path. Functions that acquire more than one resource must use the project's normal function_output path or another structured cleanup region. Release resources in reverse acquisition order and make cleanup safe after partial acquisition.
Release functions used this way must accept typed NULL as a no-op. When a release API does not, guard that call with an explicit validity check.
Contextual C example:
int EX_processFile(const char path[])
{
int ret = EXIT_SUCCESS;
file_t *file = (file_t *)(NULL);
uint8_t *buffer = (uint8_t *)(NULL);
if (path == (const char *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
file = FILE_open(path);
if (file == (file_t *)(NULL))
{
ret = -EIO;
goto function_output;
}
buffer = (uint8_t *)MEM_alloc(EX_BUFFER_SIZE);
if (buffer == (uint8_t *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
ret = EX_processBuffer(file, buffer, EX_BUFFER_SIZE);
function_output:
MEM_free(buffer);
FILE_close(file);
return ret;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Use sizeof according to the actual type of the operand:
sizeof(pointer) must never supply the capacity of pointed storage. Array parameter notation does not preserve array size because C adjusts the parameter to a pointer.
Pass the storage size with the pointer:
Noncompliant fragment (do not copy):
int EX_clearBuffer(uint8_t buffer[], size_t buffer_size)
{
int ret = EXIT_SUCCESS;
if ((buffer == (uint8_t *)(NULL)) ||
(buffer_size == 0u))
{
ret = -EINVAL;
goto function_output;
}
memset(buffer, 0, sizeof(buffer));
function_output:
return ret;
}
Contextual C example:
int EX_clearBuffer(uint8_t buffer[], size_t buffer_size)
{
int ret = EXIT_SUCCESS;
if ((buffer == (uint8_t *)(NULL)) || (buffer_size == 0u))
{
ret = -EINVAL;
goto function_output;
}
memset(buffer, 0, buffer_size);
function_output:
return ret;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Classify a structure as a value object or an identity/resource object before allowing whole-object copy.
| Object category | Struct assignment or bytewise copy |
|---|---|
| value object | permitted when its contract declares the representation copyable |
| identity object | prohibited unless a named clone operation defines new identity |
| resource object | prohibited unless a named duplication operation defines ownership |
| synchronization object | prohibited |
Objects containing owned pointers, mutexes, atomics, file descriptors, device handles, reference counts, intrusive links, callbacks, or registration state must not be copied with memcpy or plain struct assignment unless the type's contract explicitly declares that operation safe.
Use a named copy, clone, retain, duplicate, or move operation that defines failure behavior and ownership of every member.
Contextual C example:
DEVICE_cloneConfig(&dst_config, &src_config); /* value object copy API */
Noncompliant fragment (do not copy):
dst_device = src_device; /* copies lock, handle, identity, ownership */
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A pointer to a block-scope compound literal must not escape the containing scope. Production code should prefer a named object whenever a callee accepts a pointer, because the name makes lifetime and post-call inspection explicit.
Tests may use compound literals for immediate non-retaining calls when the API contract explicitly says that it does not store the pointer.
Contextual C example:
config_t config = { 0 };
config.timeout_ms = 100u;
config.retry_count = 0u;
config.is_enabled = true;
ret = MODULE_configure(module, &config);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Untrusted or externally influenced input must not select the size of an allocation whose failure policy terminates the process or system.
Such an allocation path must:
A fatal allocator may be permitted only for a small, internally bounded allocation when termination is already the documented system policy. The module must not infer trust merely because a parser converted text into an integer.
Contextual C example:
if (request_size > REQUEST_MAX_BYTES)
{
ret = -E2BIG;
goto function_output;
}
buffer = (uint8_t *)try_alloc(request_size);
Noncompliant fragment (do not copy):
buffer = (uint8_t *)fatal_alloc(request->size_bytes); /* attacker controls fatal allocation */
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Every execution context with a bounded stack must have a documented stack budget. A function on that context must not introduce a large automatic object, hidden temporary, inlined expansion, recursion depth, or call chain that can exceed the verified budget.
Rules:
The Linux submission checklist uses checkstack and treats functions with more than 512 bytes of stack as candidates for change; this project records its own target-specific limit rather than adopting that heuristic as a universal budget.linux-submit-checklist
Contextual C example:
uint8_t scratch[128] = { 0 }; /* included in reviewed stack budget */
Noncompliant fragment (do not copy):
uint8_t scratch[65536] = { 0 }; /* hidden large automatic allocation */
Class: SECURITY. Obligation: project requirement.
Apply the canonical API policy in CSTYLE-086 to direct calls and equivalent custom wrappers. Scope it to APIs available in the selected platform. A restricted API is not automatically vulnerable in every use, and an allowed API is not automatically safe. Its preconditions and product threat model still apply. Do not copy platform-specific replacements into portable modules.
Source context: cwe.
Contextual C example:
ret = STR_copy(dst, dst_capacity, src);
if (ret != EXIT_SUCCESS)
goto function_output;
Noncompliant fragment (do not copy):
strcpy(dst, src); /* banned/unbounded API */
Class: SECURITY. Obligation: project requirement.
The CBAN register below is the canonical API restriction list. ban is a project prohibition on the named use; ban-pattern prohibits the unsafe condition, not every call to the API; review requires recorded preconditions and a suitable test. These are project controls, not a claim that ISO C or CERT universally bans every listed API. A replacement wrapper must enforce the stated bounds, error, ownership, encoding, and platform contract. A _s suffix alone is not approval. The table retains all 140 existing CBAN identities.
Failure scenarios: CPIT-006, CPIT-055, CPIT-056, CPIT-059, CPIT-064, CPIT-065, CPIT-066, CPIT-093, CPIT-096, CPIT-098, CPIT-100, CPIT-103.
Source context: cwe.
Contextual C example:
ret = STR_parseU32(input, &value);
Noncompliant fragment (do not copy):
value = (uint32_t)atoi(input);
Class: CORRECTNESS. Obligation: project requirement.
String operations must preserve bounds and termination explicitly.
Failure scenarios: CPIT-055, CPIT-058, CPIT-060.
Contextual C example:
int written = 0;
if ((path == (char *)(NULL)) || (dir_path == (const char *)(NULL)) ||
(file_name == (const char *)(NULL)) || (path_size == 0u))
{
ret = -EINVAL;
goto function_output;
}
written = snprintf(path, path_size, "%s/%s", dir_path, file_name);
if ((written < 0) || ((size_t)written >= path_size))
{
ret = -ENOSPC;
goto function_output;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A pointer-plus-length view is not implicitly a C string. Its contract must state whether the bytes are text or opaque data, whether embedded NUL bytes are valid, whether a terminator is present inside or after the extent, the encoding, and the owner of the storage.
Do not pass a counted view to strlen, s, or another terminator-scanning API until a checked conversion establishes a terminated destination. Conversely, do not infer the usable extent of a C string from an unrelated buffer capacity. Prefer project span/view types or an explicit pointer and extent. nginx's core string type similarly carries len and data, and the data need not be NUL-terminated.nginx-development-guide
Contextual C example:
text_span_t span = { .data = input, .length = input_length };
ret = TEXT_parseSpan(&span);
Noncompliant fragment (do not copy):
printf("%s", input); /* input has a length but no NUL-termination contract */
Class: ARCHITECTURE / CORRECTNESS. Obligation: project requirement.
Prefer explicit module-instance state. A necessary file-scope mutable object requires a named owner, lifetime, synchronization, initialization, and shutdown contract; keep it private with static and a g_ prefix. Avoid function-static mutable state. Immutable file-scope tables may use static const.
Do not create cross-translation-unit variables or publish another module's objects by name. The only explicit extern allowed in project-authored C interfaces is the __cplusplus-guarded extern "C" compatibility block required by CMOD-019 for C++ compatible headers. Do not use it as a storage class on objects, prototypes, or inline definitions. Follow CMOD-017 through CMOD-019 for ownership, ordinary function prototypes, and header-owned compatibility blocks. Application main.c keeps its own helpers and state private under CMOD-021.
Contextual C example:
typedef struct ExampleState
{
uint32_t counter;
bool is_initialized;
} example_state_t;
int EX_increment(example_state_t *state)
{
int ret = EXIT_SUCCESS;
if (state == (example_state_t *)(NULL))
{
ret = -EINVAL;
goto function_output;
}
if (state->counter == UINT32_MAX)
{
ret = -ERANGE;
goto function_output;
}
state->counter++;
function_output:
return ret;
}
Noncompliant fragment (do not copy):
int global_counter = 0;
bool is_initialized = false;
int EX_increment(void)
{
int ret = EXIT_SUCCESS;
static int counter = 0;
counter++;
function_output:
return ret;
}
Class: CORRECTNESS / SAFETY. Obligation: project requirement.
Use volatile accesses only where the implementation/platform contract needs them, such as documented MMIO or supported signal state. Volatile is not a mutex, thread publication protocol, atomic read-modify-write, DMA cache operation, or general memory barrier. Do not introduce it to disguise a data race or suppress optimization symptoms. Isolate hardware access semantics in the target adapter.
Failure scenarios: CPIT-068, CPIT-075, CPIT-083, CPIT-086.
Contextual C example:
uint32_t reg_status = 0u; reg_status = MMIO_read32(REG_STATUS_ADDRESS);
Class: CORRECTNESS / SAFETY. Obligation: project requirement.
Classify concurrency per operation and per instance: thread-safe, externally synchronized, or confined to a thread. Also document reentrancy, blocking, allocation, ISR/signal restrictions, and concurrent destruction. Independent instances are not necessarily independent when they share allocator contexts or other mutable dependencies. A thread-safe operation can still be unbounded.
Contextual C example:
/* * Thread-safe. */ int CACHE_getItem(int key, item_t *out);
Class: CORRECTNESS / SAFETY. Obligation: project requirement.
Name the owner of thread creation, registration, thread-local storage, exit, and join. Stop new work, wake blocked workers as needed, wait for in-flight work, and only then destroy synchronization and storage. Define allocator behavior while workers exit. Prefer cooperative cancellation. A detached thread still needs a proved lifetime protocol for every object it can access.
Failure scenarios: CPIT-068, CPIT-073, CPIT-080.
Contextual C example:
int cleanup_ret = EXIT_SUCCESS;
ret = MEM_threadRegister(thread_ctx);
if (ret != EXIT_SUCCESS)
goto function_output;
/* Thread work. */
cleanup_ret = MEM_threadDeregister(thread_ctx);
if ((ret == EXIT_SUCCESS) && (cleanup_ret != EXIT_SUCCESS))
ret = cleanup_ret;
function_output : return ret;
Class: CORRECTNESS / SAFETY. Obligation: project requirement.
Name the protected state for each lock and establish a global lock-order rule. Recheck condition-variable predicates in a loop while holding the required lock. Do not destroy reachable or locked synchronization objects. Use the weakest atomic ordering only after documenting the needed happens-before relationship; start with a simple proved protocol, not automatic relaxed operations. Release/acquire publication requires the acquiring operation to observe the corresponding release or its valid release sequence. Reclamation is a separate obligation from publication. Avoid unknown callbacks while holding locks.
Failure scenarios: CPIT-068, CPIT-069, CPIT-070, CPIT-071, CPIT-072, CPIT-074, CPIT-078, CPIT-079, CPIT-082.
Contextual C example:
bool is_locked = false;
int unlock_ret = EXIT_SUCCESS;
ret = THREAD_mutexLock(&queue_mutex);
if (ret != EXIT_SUCCESS)
goto function_output;
is_locked = true;
while (queue_is_empty)
{
ret = THREAD_condWait(&queue_cond, &queue_mutex);
if (ret != EXIT_SUCCESS)
goto function_output;
}
function_output : if (is_locked)
{
unlock_ret = THREAD_mutexUnlock(&queue_mutex);
if ((ret == EXIT_SUCCESS) && (unlock_ret != EXIT_SUCCESS))
ret = unlock_ret;
}
return ret;
Contextual C example:
atomic_store_explicit(&is_ready, true, memory_order_release); ready = atomic_load_explicit(&is_ready, memory_order_acquire);
Class: CORRECTNESS / SAFETY. Obligation: project requirement.
For allocator caches, pools, refcounts, free lists, and GC metadata, review publication, concurrent mutation, reclamation, ABA, counter overflow, teardown, lock ordering, and bounded progress separately. Hazard pointers and epochs can protect lifetime only under their complete protocols; they do not repair every logical ABA problem. A stress test is evidence of exercised schedules, not a proof that all schedules are safe. Use simpler locking when no proved lock-free protocol is justified.
Layout example (not executable):
Concurrency review records: shared object, writer contexts, reader contexts, lock/atomic primitive, ordering, lifetime, blocking rules
Noncompliant fragment (do not copy):
Layout, diagnostic, or contract example. This block is not executable C.
Shared queue is called “thread-safe” but nobody records which fields race, who writes them, or which lock/order protects them
Class: CORRECTNESS / SAFETY. Obligation: project requirement.
Document objects shared with interrupt context and the target's access and nesting rules. Use a supported critical section or proven lock-free atomic protocol; a library atomic may internally lock and therefore be unsuitable in an ISR. Masking local interrupts does not synchronize another CPU or a DMA engine. Include compiler ordering, CPU barriers, cache maintenance, and device ownership transfers when required by the hardware manual.
Failure scenarios: CPIT-068, CPIT-076.
Contextual C example:
static volatile uint32_t g_event_flags = 0u;
/* The platform ISR ABI requires void. */
/* This adapter has a documented deviation. */
void ISR_onEvent(void)
{
ISR_ATOMIC_fetchOrU32(&g_event_flags, EVENT_FLAG_RX);
}
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
A signal handler may use only operations permitted by the selected C/POSIX and runtime contract. Do not call allocation, stdio logging, or ordinary mutex operations from it. Keep shared handler state in the specifically permitted signal-safe or lock-free atomic form. An ISR and a POSIX signal handler are different execution models; do not transfer assumptions between them.
Failure scenarios: CPIT-068, CPIT-077.
Contextual C example:
static volatile sig_atomic_t g_stop = 0;
void onSignal(int sig)
{
g_stop = 1;
}
Noncompliant fragment (do not copy):
void onSignal(int sig)
{
printf("stop\n");
malloc(16u);
}
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Use the explicit pointer casts required by CSTYLE-078 and CSTYLE-107. Otherwise, a cast must express an intentional conversion, not suppress a type diagnostic. Narrow only after checking the source value's range. Preserve qualifiers and match callback types exactly. Pointer/integer and representation conversions belong to qualified low-level adapters with stated width, alignment, effective-type, lifetime, and provenance assumptions. Explain non-obvious adapter casts at the conversion or in its referenced contract.
Failure scenarios: CPIT-010, CPIT-024, CPIT-027.
Source context: c23.
Contextual C example:
uint8_t *buffer_ptr = (uint8_t *)(NULL);
uint32_t value_u32 = 0u;
uint64_t checked_value = 0u;
if (raw_value < 0)
{
ret = -ERANGE;
goto function_output;
}
checked_value = (uint64_t)raw_value;
if (checked_value > (uint64_t)UINT32_MAX)
{
ret = -ERANGE;
goto function_output;
}
value_u32 = (uint32_t)checked_value;
buffer_ptr = (uint8_t *)base_ptr;
Noncompliant fragment (do not copy):
value_u32 = (uint32_t)ptr_value;
Contextual C example:
/* Platform adapter: the MCU defines this address as a 32-bit MMIO object. */ reg_ptr = (volatile uint32_t *)register_base;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A project cast must not remove const qualification. If an external API has an incorrect mutable parameter for data it does not modify, isolate that call in a reviewed adapter and document the external contract. The adapter must not permit the callee to modify a genuinely const object.
Change the callee contract or make a validated mutable copy when modification is required. Casting away the qualifier does not make a const object writable.
Noncompliant fragment (do not copy):
mutable_config = (config_t *)config;
Class: CORRECTNESS. Obligation: project requirement.
Numeric conversions must preserve value and meaning.
Failure scenarios: CPIT-025, CPIT-046, CPIT-052, CPIT-053, CPIT-055, CPIT-063.
Source context: c23.
Complete example: worked sources.
Contextual C example:
uint16_t value_u16 = 0u;
uint32_t value_u32 = 0u;
if (value < 0)
{
ret = -ERANGE;
goto function_output;
}
value_u32 = (uint32_t)value;
if (value_u32 > (uint32_t)UINT16_MAX)
{
ret = -ERANGE;
goto function_output;
}
value_u16 = (uint16_t)value_u32;
Noncompliant fragment (do not copy):
value_u16 = (uint16_t)value;
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Access objects only through types permitted by the selected C edition's effective-type and aliasing rules. Character-type access may inspect object representation; prefer unsigned char for byte values. A representation copy using memcpy still needs valid storage, sufficient size, and an appropriate result representation. It does not perform byte-order conversion. Use restrict only under a proved contract for the relevant execution. Keep base owners distinct from cursors. Do not reconstruct usable ordinary pointers from persisted or untrusted integers. Target-specific allocator address handling needs documented provenance assumptions and toolchain tests.
Failure scenarios: CPIT-021, CPIT-022, CPIT-023.
Source context: c23.
Contextual C example:
memcpy(&value_u32, bytes, sizeof(value_u32));
Noncompliant fragment (do not copy):
value_u32 = *((uint32_t *)bytes);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Before any dereference, the current control-flow path must establish that the pointer has valid provenance, suitable alignment, an active lifetime, and permission for the requested access. A nullable pointer must also be proven non-NULL.
Prefer an explicit precondition:
An API boundary check, a successful lookup, a documented required-pointer contract, or a dominating branch may establish validity. A stale check from a different path does not.
Noncompliant fragment (do not copy):
value = ptr->value;
Contextual C example:
if (ptr != (const item_t *)(NULL))
value = ptr->value;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
No more than one pointer dereference may occur in one member-access expression. Store each pointer-valued member in a named local, establish its validity, and only then dereference it.
The rule counts pointer dereference operations, not member-access tokens. Access through an embedded object does not introduce another pointer dereference.
| Form | Status | Reason |
|---|---|---|
| object->field | permitted | one pointer dereference |
| object->embedded.field | permitted | one pointer dereference, then object access |
| object->embedded.subfield | permitted | one pointer dereference, then object access |
| object->ptr->field | prohibited | two pointer dereference operations |
| (object->ptr)->field | prohibited | two explicit pointer dereference operations |
| object->ptr->ptr->field | prohibited | three pointer dereference operations |
If an approved deviation must retain a chain, parentheses must expose every additional dereference boundary. Write (aux->prev)->next, not aux->prev->next; for a longer chain, name or parenthesize each intermediate pointer in the same manner. The deviation must document how each pointer's validity and lifetime were established.
Noncompliant fragment (do not copy):
(aux->prev)->next = aux->next; (context->owner)->callback(context);
Contextual C example:
node_t *prev = (node_t *)(NULL);
node_t *next = (node_t *)(NULL);
if (aux != (node_t *)(NULL))
{
prev = aux->prev;
next = aux->next;
}
if (prev != (node_t *)(NULL))
prev->next = next;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A call that may change ownership, lifetime, allocation, container structure, or object identity invalidates earlier pointer-validity evidence. Re-establish validity after the call before dereferencing the pointer. Only an explicit callee contract may preserve the earlier guarantee.
Prefer reacquiring the object through a stable key:
Noncompliant fragment (do not copy):
if (node != (node_t *)(NULL))
{
LIST_remove(list, node);
node->flags = 0u;
}
Contextual C example:
if (node != (node_t *)(NULL))
{
node_id = node->id;
LIST_remove(list, node);
node = LIST_find(list, node_id);
}
if (node != (node_t *)(NULL))
node->flags = 0u;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Do not perform interleaved read-modify-write operations through pointers that may name the same object. Prove that the objects do not overlap, or select one canonical pointer and perform the state transition through it.
Prefer an explicit non-aliasing precondition:
Noncompliant fragment (do not copy):
first->value += delta; second->value = first->value;
Contextual C example:
if ((first == (item_t *)(NULL)) || (second == (item_t *)(NULL)) ||
(first == second))
{
ret = -EINVAL;
goto function_output;
}
first->value += delta;
second->value = first->value;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Before indexing an array, prove that the index is within the bounds of that same array object. A global maximum, unrelated capacity, or different buffer's length does not establish the bound.
Pointer arithmetic is permitted only within one array object. Code may form a one-past pointer for comparison or iteration, but it must not dereference that pointer.
Prefer pointer-and-count contracts that travel together:
Avoid checking an unrelated limit:
Contextual C example:
if ((items != (item_t *)(NULL)) && (index < item_count))
item = &items[index];
Noncompliant fragment (do not copy):
if (index < ITEM_MAX)
{
item = &items[index];
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
For every pointer member, the type or API contract must state whether the member is owned, borrowed, optional, required, or a weak reference. It must also state the lifetime and allocator family when either affects use or release.
Embedded objects and pointer members have different access and ownership semantics:
After context validity is established, context->config.timeout_ms performs one pointer dereference. Accessing the device requires a separate local pointer and validity proof under CSTYLE-122.
Contextual C example:
typedef struct Context
{
config_t config; /* Embedded; owned by this context. */
/* Borrowed and optional; the device owner retains lifetime control. */
device_t *device;
} context_t;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Converting raw, arena, packet, DMA, shared, or byte-array storage to a typed object pointer requires a documented proof of:
Use alignof(type) and alignas(type) through the project portability layer instead of copying a numeric alignment assumption.
The byte copy above establishes a representation copy. It does not create permission to retain an arbitrary record_t * into storage after the storage lifetime ends.
Contextual C example:
alignas(record_t) uint8_t storage[sizeof(record_t)] = { 0 };
record_t record = { 0 };
record.value = input_value;
memcpy(storage, &record, sizeof(record));
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Standard offsetof may verify a layout contract. Recovering an enclosing object from an interior member pointer is prohibited outside one reviewed intrusive- container or platform adapter.
That adapter must document the containing type, member, alignment, complete- object lifetime, provenance model, and null behavior. Application modules must not open-code pointer subtraction with offsetof.
Contextual C example:
node_t *node = CONTAINER_FROM_LINK(link, node_t, link);
Noncompliant fragment (do not copy):
node_t *node = (node_t *)((uint8_t *)link - offsetof(node_t, link)); /* open-coded everywhere */
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Every pointer that represents a sequence must travel with an explicit extent contract. The extent may be an element count, byte count, capacity, begin/end pair, or fixed compile-time contract. The unit and nullable/empty semantics must be part of the API.
Do not use sizeof on an array parameter to infer the caller's extent. Within the function, the parameter has pointer type regardless of its bracket spelling.
Contextual C example:
int PROCESS_samples(const uint16_t *samples, size_t sample_count);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
An object that one execution context can discover while another context can remove or destroy it must have one documented lifetime-retention protocol. Approved protocols include ownership transfer, a lock that protects lookup and lifetime, a checked reference-count acquisition, RCU/epoch reclamation, or an approved hazard-pointer scheme.
A pointer lookup and a later reference increment do not form a safe protocol unless the object cannot reach its terminal state between those operations. Linux kref rules require serialization when code obtains a reference without already holding a valid reference.linux-kref
Contextual C example:
int SESSION_useById(session_id_t id)
{
int ret = EXIT_SUCCESS;
session_t *session = (session_t *)(NULL);
ret = SESSION_lookupRetained(id, &session);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = SESSION_process(session);
function_output:
SESSION_release(&session);
return ret;
}
Noncompliant fragment (do not copy):
session = SESSION_lookupBorrowed(id);
if (session == (session_t *)(NULL))
{
ret = -ENOENT;
goto function_output;
}
ret = SESSION_process(session);
function_output:
return ret;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Process-wide or module-wide one-time initialization must use the project once primitive or another reviewed synchronization protocol. The protocol must make all initialized state visible before another execution context observes the initialized condition.
Do not implement concurrent initialization with an unsynchronized boolean or a hand-written double-checked pattern.
Contextual C example:
int LIBRARY_initialize(void)
{
int ret = EXIT_SUCCESS;
ret = ONCE_execute(&g_library_once, library_initializeOnce,
(void *)(NULL));
function_output:
return ret;
}
Noncompliant fragment (do not copy):
if (!g_initialized)
{
LIBRARY_buildTables();
g_initialized = true;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A profile that supports asynchronous or deferred thread cancellation must state where cancellation can occur. Code that owns a lock, allocation, descriptor, transaction, or registered callback at a cancellation point must install a cleanup action or disable cancellation for the bounded critical region.
Ordinary modules should consume a project cancellation abstraction instead of scattering native cleanup macros. POSIX cleanup handlers run when cancellation unwinds a thread and can release locks or other resources.pthread-cleanup
Contextual C example:
int WORKER_update(worker_t *worker)
{
int ret = EXIT_SUCCESS;
cancel_state_t cancel_state = { 0 };
ret = THREAD_cancelDisable(&cancel_state);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = WORKER_updateCritical(worker);
THREAD_cancelRestore(&cancel_state);
function_output:
return ret;
}
Noncompliant fragment (do not copy):
ret = MUTEX_lock(&worker->lock);
if (ret != EXIT_SUCCESS)
{
goto function_output;
}
ret = IO_waitForInput(worker->fd);
MUTEX_unlock(&worker->lock);
function_output:
return ret;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A POSIX profile should prefer the project process-spawn abstraction. If an owner uses fork() after the process has created threads, the child may execute only async-signal-safe operations until execve() or _exit(). The child must not allocate memory, take inherited application locks, call the logger, invoke module callbacks, or touch state that another parent thread could have held mid-update. Linux documents that only the calling thread survives in the child and restricts the child to async-signal-safe calls until execve().linux-fork-threaded
Contextual C example:
int JOB_launch(const process_spec_t *spec)
{
int ret = EXIT_SUCCESS;
ret = PROCESS_spawn(spec);
function_output:
return ret;
}
Noncompliant fragment (do not copy):
child_pid = fork();
if (child_pid == 0)
{
LOG_info("child starting");
WORKER_lockGlobalState();
execve(path, argv, envp);
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A real-time or bounded-latency profile must document the maximum hold time and maximum wait time for every lock reachable from the critical path. If a higher- priority task can block on a resource owned by a lower-priority task, the owner must select a protocol such as priority inheritance, priority ceiling, ownership partitioning, or a lock-free handoff that preserves the timing requirement.
Do not call unbounded external code, blocking I/O, allocation, or arbitrary callbacks while holding a real-time lock. Linux RT mutexes use priority inheritance to bound the classic unbounded priority-inversion case. linux-rt-mutex
Contextual C example:
int CONTROL_update(control_t *control, const control_input_t *input)
{
int ret = EXIT_SUCCESS;
ret = RT_MUTEX_lock(&control->lock);
if (ret != EXIT_SUCCESS)
goto function_output;
control_updateStateLocked(control, input);
RT_MUTEX_unlock(&control->lock);
function_output:
return ret;
}
Noncompliant fragment (do not copy):
ret = MUTEX_lock(&control->lock);
if (ret != EXIT_SUCCESS)
{
goto function_output;
}
ret = NETWORK_waitForReply(control->socket);
if (ret == EXIT_SUCCESS)
{
ret = control->callbacks->notify(control->callbacks->context);
}
MUTEX_unlock(&control->lock);
function_output:
return ret;
Class: CORRECTNESS. Obligation: project requirement.
Prevent undefined behavior before evaluating the affected expression. Check bounds before forming out-of-range pointers, and check arithmetic before an overflowing operation. Require initialized values and live objects. A successful NULL check, passing test, or low optimization level does not make an invalid access defined. Sanitizers complement review but do not detect every undefined behavior on every executed path.
Failure scenarios: CPIT-014, CPIT-015, CPIT-017.
Failure fragment (do not execute):
Function-body fragment. index and item_count are size_t; items refers to a validated array containing item_count elements. Pointer validity and lifetime are preconditions, not inferred from a non-NULL value.
value = items[item_count];
Contextual example:
Function-body fragment. index and item_count are size_t; items refers to a validated array containing item_count elements. Pointer validity and lifetime are preconditions, not inferred from a non-NULL value.
if (index >= item_count)
{
ret = -ERANGE;
goto function_output;
}
value = items[index];
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Distinguish undefined behavior, implementation-defined behavior, unspecified behavior, and a defined operation that violates the product contract. Do not rely on undefined behavior. Record implementation-defined choices in the target profile. Do not depend on one evaluation order when C leaves it unspecified. Defined unsigned wraparound may still violate a size, deadline, or security invariant and must be justified at the use site.
Failure scenarios: CPIT-019, CPIT-020, CPIT-034, CPIT-037, CPIT-041, CPIT-044.
Source context: c23.
Layout example (not executable):
Target assumption file classifies each relied-on behavior as defined, implementation-defined, unspecified, or prohibited UB and ties implementation-defined choices to toolchain evidence
Noncompliant fragment (do not copy):
Layout, diagnostic, or contract example. This block is not executable C.
Code relies on signed overflow, object representation, or shift behavior because “it works with our current compiler” without classifying the C behavior
Class: CORRECTNESS. Obligation: project requirement.
Check signed arithmetic before overflow and unsigned size arithmetic before unintended wraparound. Shift counts must be nonnegative and below the width of the promoted left operand. Use suitable unsigned operands for masks and avoid assuming narrow integer operands remain narrow after promotion. Distinguish intentional modular arithmetic from bounds calculations. The target profile must define any relied-on signed-shift behavior.
Failure scenarios: CPIT-034, CPIT-038, CPIT-039.
Source context: c23.
Complete example: worked sources.
Contextual example:
Function-body fragment after validating shift as a nonnegative uint32_t count. Include <stdint.h> and the error header. ret is first at function entry. The fixed width belongs to the uint32_t operand, not to an assumed width of int.
uint32_t result_u32 = 0u;
uint32_t value_u32 = 0u;
if (shift >= 32u)
{
ret = -ERANGE;
goto function_output;
}
value_u32 = 1u;
result_u32 = value_u32 << shift;
Class: CORRECTNESS. Obligation: project requirement.
Use a checked arithmetic foundation API with a documented overflow result and output-state guarantee. C23 <stdckdint.h> is an option when the qualified toolchain provides it. Compiler builtins belong in an adapter; portable bounds checks are a supported fallback. Do not test overflow by first computing a signed overflowing result. Test zero, exact limits, and one beyond each limit.
Failure scenarios: CPIT-018, CPIT-046, CPIT-047, CPIT-048, CPIT-049, CPIT-050, CPIT-068, CPIT-081.
Source context: c23.
Complete example: worked sources.
Contextual C example:
size_t total_size = 0u;
bool has_overflow = false;
has_overflow = ARITH_addSize(header_size, payload_size, &total_size);
if (has_overflow)
{
ret = -ENOMEM;
goto function_output;
}
Contextual C example:
size_t alignment_adjustment = 0u;
bool has_overflow = false;
if ((align == 0u) || ((align & (align - 1u)) != 0u))
{
ret = -EINVAL;
goto function_output;
}
alignment_adjustment = align - 1u;
has_overflow = ARITH_addSize(size, alignment_adjustment, &rounded_size);
if (has_overflow)
{
ret = -ENOMEM;
goto function_output;
}
rounded_size &= ~alignment_adjustment;
Class: CORRECTNESS. Obligation: project requirement.
Reject a zero divisor before / or %. For signed types, also reject the minimum representable value divided or reduced modulo negative one when the mathematical quotient cannot be represented. Validate externally derived divisors and intermediate results. Do not assume a processor exception supplies the required C or product error behavior.
Failure scenarios: CPIT-034, CPIT-040, CPIT-046, CPIT-051.
Source context: c23.
Contextual C example:
if (divisor == 0)
{
ret = -EDOM;
goto function_output;
}
if ((dividend == INT_MIN) && (divisor == -1))
{
ret = -ERANGE;
goto function_output;
}
quotient = dividend / divisor;
remainder = dividend % divisor;
Class: CORRECTNESS. Obligation: project requirement.
Use named protocol or register masks and a suitable unsigned integer domain. Validate shift counts and unknown bits. A bitmask field is not necessarily a sequential enum. State which bits the module may modify and how reserved bits are handled. Avoid using a native C bitfield layout as a portable wire format.
Contextual C example:
#define PERM_FLAG_READ ((uint32_t)(1U << 0U)) /* bit 0 */
#define PERM_FLAG_WRITE ((uint32_t)(1U << 1U)) /* bit 1 */
#define PERM_FLAG_EXEC ((uint32_t)(1U << 2U)) /* bit 2 */
uint32_t permissions = 0u;
permissions = PERM_FLAG_READ | PERM_FLAG_WRITE;
if ((permissions & PERM_FLAG_EXEC) != 0u)
EX_runExecutable();
Noncompliant fragment (do not copy):
if ((permissions & 0x05u) != 0u)
EX_runExecutable();
Class: CORRECTNESS / SAFETY. Obligation: project requirement.
Follow the device manual for access width, alignment, ordering, and read/write side effects. Read-clear, write-one-to-clear, write-only, and set/clear alias registers cannot be handled by a generic read-modify-write recipe. Reserved bits must receive the manual's required values, which are not always their old values. Handle competing writers and interrupt/DMA interaction through the target protocol. A volatile pointer alone does not supply these guarantees.
Failure scenarios: CPIT-034, CPIT-083, CPIT-084, CPIT-085.
Contextual C example:
#define REG_CTRL_ENABLE_MASK ((uint32_t)(1U << 0U)) #define REG_CTRL_MODE_MASK ((uint32_t)(3U << 4U)) uint32_t reg_value = 0u; /* REG_CTRL is documented as ordinary read/write; RMW is permitted. */ reg_value = MMIO_read32(REG_CTRL_ADDRESS); reg_value &= ~REG_CTRL_MODE_MASK; reg_value |= REG_CTRL_ENABLE_MASK; MMIO_write32(REG_CTRL_ADDRESS, reg_value);
Class: CORRECTNESS / SAFETY. Obligation: project requirement.
Do not use floating point for allocator-core addresses, capacities, alignment, or metadata sizing. This is a project restriction aimed at exact integer invariants, not a claim that every floating-point operation is undefined or nondeterministic. Non-core tools may use floating point under a documented precision, rounding, exceptional-value, and target policy.
Failure scenarios: CPIT-046, CPIT-055.
Contextual C example:
if (!isfinite(sensor_value))
{
ret = -ERANGE;
goto function_output;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
bool represents a logical predicate, not a numeric, error, count, flag word, or multi-state domain. Do not rely on implicit conversion of a status, byte count, descriptor, or enum into a boolean result.
Use a status type for fallible actions and an enum for three or more states. Do not use boolean arithmetic such as adding a predicate directly to a counter; make the conditional state transition explicit.
Contextual C example:
bool is_ready = false; mode_t mode = MODE_IDLE;
Noncompliant fragment (do not copy):
bool state = 2; /* multi-state domain forced into bool */
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Use &&, ||, and ! for logical state. Use &, |, ^, and ~ for documented bit patterns. A bit-mask test must compare the masked value explicitly with zero or the expected mask.
Do not substitute bitwise operators for logical operators merely to remove a branch. Constant-time code uses a reviewed security primitive with a separate contract.
Contextual C example:
if (is_ready && is_enabled)
ret = EX_start();
if ((flags & FLAG_READY) != 0u)
ready_count++;
Class: PROJECT_STYLE / CORRECTNESS / ANALYZABILITY. Obligation: project requirement.
Declare and initialize all automatic variables at the beginning of the function, before argument validation or other executable statements. Do not declare or initialize variables inside a loop or a scope smaller than the function. Assignments after declaration are allowed; they are not new declarations.
The return variable comes first: normally int ret initialized to success, or the contract-required result type permitted by CSTYLE-064. Group remaining declarations as arrays, structs, enums, pointers, and common scalar variables. Within a category use this order where applicable: void *, module-specific types, other custom types, char variants, double variants, float variants, size_t, uintptr_t/intptr_t, fixed-width unsigned integers, and int variants.
Pointers start as typed NULL. Arrays and structs use semantic aggregate initialization such as { 0 }; enums use their documented initial value; numeric scalars start from a zero-like literal with the appropriate suffix. Booleans start as false. Assign required nonzero operational values only after argument validation. Read-only constants may be macros or immutable file-scope tables, outside this automatic-variable rule.
A zero-like initializer is bookkeeping, not permission to use an invalid object or activate hardware. Establish the required safe operating state before the first effect or publication. A descriptor with zero as a valid resource needs a separate acquired flag or a validated sentinel assignment before cleanup could release it. Do not replace semantic initialization with memset for arbitrary pointer or floating-point members.
Use the corresponding pointer cast for every explicit NULL, as required by CSTYLE-078. Cleanup variables also belong at function entry; no declaration may appear after function_output.
Failure scenarios: CPIT-012, CPIT-034, CPIT-036, CPIT-083, CPIT-088.
Complete example: worked sources.
Contextual example:
Function definition. Include <stdint.h>, <stdlib.h>, <errno.h> and its own declaring header. Both pointers must refer to live correctly aligned uint32_t objects. This does not validate arbitrary non-NULL addresses.
int SAMPLE_readValue(const uint32_t *source, uint32_t *value_out)
{
int ret = EXIT_SUCCESS;
uint32_t value = 0u;
if ((source == (const uint32_t *)(NULL)) ||
(value_out == (uint32_t *)(NULL)))
{
ret = -EINVAL;
goto function_output;
}
value = *source;
*value_out = value;
function_output:
return ret;
}
Class: PORTABILITY / CORRECTNESS. Obligation: project requirement.
Use bounded arrays with compile-time constant extents in the portable project profile. VLAs and alloca are prohibited. Use { 0 } or designated initializers for semantic initialization; do not assume memset is equivalent for arbitrary object types. C23 empty initialization is permitted only in a qualified C23 profile. GNU range designators remain an extension. Account for stack usage and task/interrupt nesting, not only an individual array's size. Automatic declarations still follow CSTYLE-107: initial aggregate values are zero-like at function entry; operational member/element assignments follow validation. Nonzero immutable fixture tables in the example have file scope.
Related controls: CSTYLE-001, CSTYLE-108.
Failure scenarios: CPIT-034, CPIT-042.
Source context: c23.
Complete example: worked sources.
Contextual C example:
int arr[MAX_LEN] = { 0 };
Contextual C example:
typedef enum Status
{
STATUS_OFF = 0u,
STATUS_ON = 1u,
STATUS_MAX = 2u
} status_t;
status_t status_array[STATUS_MAX] = {
[STATUS_OFF] = STATUS_ON,
[STATUS_ON] = STATUS_OFF,
};
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Use C initialization syntax to establish the semantic default value of a typed object. Writing zero bytes with memset() may establish that value only when the type's documented representation contract defines all-bits-zero as its semantic default.
Avoid treating an arbitrary representation as a semantic value:
memset() remains appropriate for raw byte buffers and types with an explicit all-bits-zero contract. It is not a secure-erasure primitive; secret clearing must use the project secure-zero wrapper required by the standard-library policy.
Contextual C example:
config_t config = { 0 };
Noncompliant fragment (do not copy):
config_t config; memset(&config, 0, sizeof(config));
Class: SECURITY. Obligation: project requirement.
Untrusted data must remain data when passed to another interpreter or language.
Failure scenarios: CPIT-093, CPIT-095, CPIT-103, CPIT-105, CPIT-106, CPIT-107, CPIT-109.
Contextual C example:
ret = DB_queryPrepared(db, "SELECT * FROM account WHERE id=?", account_id);
Noncompliant fragment (do not copy):
snprintf(query, sizeof(query), "SELECT * FROM account WHERE id=%s", user_input);
Class: SECURITY. Obligation: project requirement.
Critical operations must authenticate and authorize at the trusted boundary.
Failure scenarios: CPIT-093, CPIT-105, CPIT-108, CPIT-112, CPIT-113.
Source context: authorization.
Contextual C example:
ret = AUTH_requireCapability(session, CAP_WRITE_CONFIG);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = CONFIG_write(request);
Noncompliant fragment (do not copy):
CONFIG_write(request); /* possession of object_id treated as authority */
Class: SECURITY. Obligation: project requirement.
Decode untrusted structured input into explicit semantic data before it can become runtime state.
Failure scenarios: CPIT-094, CPIT-105, CPIT-110, CPIT-111, CPIT-122.
Source context: validation; upload; xxe.
Contextual C example:
ret = PARSER_decodeBounded(input, input_size, &dto);
if (ret != EXIT_SUCCESS)
goto function_output;
Noncompliant fragment (do not copy):
runtime_object = *((runtime_object_t *)input); /* raw bytes become privileged runtime object */
Class: SECURITY. Obligation: project requirement.
Apply an explicit outbound destination policy to schemes, ports, resolved addresses, redirects, proxies, and credentials. Validate the actual connection destination so that a second DNS resolution cannot bypass the decision. Bound redirects, response size, work, and connection/read time. Restrict network egress where the deployment permits it. A syntactically valid URL is not an authorized destination. See the SSRF source and the product's service policy.
Failure scenarios: CPIT-105, CPIT-114.
Source context: ssrf.
Contextual C example:
ret = NET_validateDestination(url, &approved_endpoint);
if (ret == EXIT_SUCCESS)
ret = HTTP_get(&approved_endpoint, reply);
Noncompliant fragment (do not copy):
ret = HTTP_get(request->url, reply); /* attacker controls SSRF destination */
Class: SECURITY. Obligation: project requirement.
Every externally influenced resource needs a hard engineering budget. Budget as applicable:
Failure scenarios: CPIT-045, CPIT-046, CPIT-083, CPIT-093, CPIT-105, CPIT-115.
Source context: validation.
Contextual C example:
if (request->item_count > REQUEST_MAX_ITEMS)
{
ret = -E2BIG;
goto function_output;
}
Noncompliant fragment (do not copy):
for (i = 0u; i < request->item_count; i++)
{
allocateItem();
} /* unbounded external work */
Class: SECURITY. Obligation: project requirement.
Deny the protected operation after failed authentication, authorization, integrity, freshness, configuration, or policy checks. Do not let missing data, timeouts, parse errors, or storage errors select a more permissive branch. Use stable external errors and retain approved internal diagnostics without secrets. If denying an operation conflicts with physical safety, the hazard analysis must define the safe degraded state; neither a blanket shutdown nor continued operation is universally safe.
Failure scenarios: CPIT-068, CPIT-088, CPIT-105, CPIT-120.
Source context: authorization.
Contextual C example:
if (security_config_valid)
authorization_required = true;
else
ret = -EACCES;
Noncompliant fragment (do not copy):
if (!security_config_valid)
{
authorization_required = false; /* permissive fallback */
}
Class: SECURITY. Obligation: project requirement.
Runtime code and privileged tools must not let untrusted search state choose executable content.
Failure scenarios: CPIT-105, CPIT-118, CPIT-121.
Source context: supply-chain.
Contextual C example:
ret = LOADER_openApproved("/usr/lib/project/plugin.so", &plugin);
Noncompliant fragment (do not copy):
plugin = dlopen(getenv("PLUGIN_PATH"), RTLD_NOW);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Comments shall add information that the executable statements cannot express cleanly: ownership, ordering, hardware behavior, protocol constraints, invariants, workarounds, proof assumptions, or the reason an apparently simpler implementation is wrong. Do not narrate straightforward syntax line by line.
A comment attached to a workaround must name the constraint that keeps the workaround necessary. A copied or moved block must carry only comments that remain true at the new location.
Use the C Documentation Standard to construct the file and entity comment blocks in source order, select required/optional fields, and validate Doxygen output.
Contextual example:
Contract-header excerpt; include <stddef.h>. The comment states the lifetime that the signature cannot encode.
/* The callback borrows input only until it returns. */
typedef int (*sink_write_cb_t)(void *context, const unsigned char *input,
size_t input_size_bytes);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Do not keep disabled implementation code in comments. Version control owns source history. Temporary diagnostic code belongs in a local change or an explicit debug build feature with an owner and removal policy.
Comments may contain short pseudo-code or examples when they document an algorithm; they must not function as an alternate implementation waiting to be uncommented.
Contextual example:
Public declaration for the maintained implementation. Removed implementations remain in version control, not as commented-out alternate code.
int MODULE_process(module_t *module);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Do not split a stable diagnostic, assertion message, panic string, protocol token, or other text that engineers are expected to search literally merely to satisfy the line-length limit. Keep the exception narrow; ordinary prose and long user text still follow the existing line-breaking rules.
Linux, FreeBSD, PostgreSQL, and OpenSSL all preserve grep-friendly diagnostics for this reason.
Contextual example:
Adapter-only logging fragment. log_context and frame_id are validated; the wrapper owns printf compatibility. Keep this diagnostic phrase intact for searching.
LOG_error(log_context, "frame checksum mismatch: id=%u", frame_id);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Source files shall not contain Vim modelines, Emacs local-variable blocks, or other file-local directives that silently alter editor execution or developer settings. Repository-owned formatter, .editorconfig, lint, and CI configuration may define project behavior in reviewable files.
Contextual example:
Header excerpt. Editor configuration belongs in repository tooling, not per-file modelines.
#if !defined(SAMPLE_PACKET_H) #define SAMPLE_PACKET_H #include <stddef.h> int PACKET_validateSize(size_t packet_size_bytes); #endif
Class: PROJECT_POLICY. Apply the scope and requirement words below.
A public ABI header may target an older or narrower C language subset than private implementation files. The supported public baseline must be named in the build and compatibility policy, and public declarations shall not force consumers to enable a newer language mode merely because the implementation uses it.
FFmpeg keeps public headers at C99 while implementation code uses C11; systemd uses a similarly conservative public surface. This project may choose a different pair of baselines, but the distinction must be explicit and tested.
Contextual example:
The public header uses the approved common language subset; CI compiles it with every supported consumer dialect.
#if !defined(SAMPLE_PUBLIC_H) #define SAMPLE_PUBLIC_H #include <stddef.h> typedef struct Sample sample_t; int SAMPLE_capacity(const sample_t *sample, size_t *capacity_bytes); #endif
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
If correct output depends on implementation-defined behavior, document the exact assumption and bind it to a supported target or toolchain contract. Examples include plain-char signedness, integer widths not guaranteed by the selected type, object alignment extensions, bit-field layout, arithmetic right shift of negative signed values, and ABI calling conventions.
Build or startup assertions should check assumptions that can be checked. Zephyr's coding guidelines make this traceability requirement explicit.
Contextual example:
Translation-unit scope, after <limits.h>. Reject the unsupported representation rather than silently changing the protocol.
_Static_assert(CHAR_BIT == 8, "This wire profile requires eight-bit bytes");
Class: PROJECT_POLICY. Apply the scope and requirement words below.
A symbol provided by a linker script or assembly file is not an ordinary C object unless the producer defines it as one. A low-level boundary adapter must document whether the symbol denotes an address, a byte range, a size/value, or actual storage.
When the platform boundary exposes linker information to C, use a normal function prototype backed by an accessor implemented for that platform, including assembly when necessary. Document its C calling convention and result representation. Do not add an explicit extern object declaration, even in an adapter, or replace it with a tentative definition that allocates unrelated storage. The sole explicit extern exception remains the guarded C++ linkage block in CMOD-019.
Contextual example:
Platform accessor declaration; include <stddef.h> where this interface's profile permits it. The implementation owns access to the raw platform symbols.
int PLATFORM_firmwareRange(const unsigned char **begin_out,
size_t *size_bytes_out);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
A language feature or compiler extension outside the project's minimum supported baseline requires either a compile-time feature probe plus a behaviorally equivalent fallback, or an explicit target/profile restriction. Version-number guessing alone is not sufficient when the toolchain offers feature-test facilities.
PostgreSQL, Git, FFmpeg, systemd, HAProxy, and other portable projects use this pattern to gain newer compiler facilities without silently shrinking their supported platform set.
Contextual example:
Compiler-adapter header, not ordinary module code. Both private implementations preserve the same overflow/output contract.
#if defined(PROJECT_HAS_CHECKED_ARITHMETIC) #include "checked_native.h" #else #include "checked_portable.h" #endif
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Treat compiler and static-analysis warnings as defects until review establishes that the construct is correct. When a warning is a repeatable false positive for an approved construct, suppress it at the narrowest practical scope and record the tool, diagnostic identifier, reason, and applicable configuration.
Do not add meaningless casts, dead assignments, unreachable branches, or performance regressions solely to silence a tool. Project-wide suppressions require an owner and periodic review.
Contextual example:
Function-body fragment. source_value is uint32_t; narrow_value and ret are declared at entry. No warning suppression replaces this check.
if (source_value > UINT16_MAX)
{
ret = -ERANGE;
goto function_output;
}
narrow_value = (uint16_t)source_value;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Generated C, headers, tables, decoder code, or register definitions must identify the generator and input source in a reproducible way. Do not hand-edit generated output unless the generation workflow explicitly designates an editable region.
CI should regenerate deterministic outputs and fail when committed generated files are stale. A generated file does not bypass the public ABI, unsafe-API, or security rules that apply to the artifact it becomes.
Contextual example:
Build manifest fields. Regeneration checks compare real digests; editing generated C without updating its generating input violates this contract.
typedef struct GeneratedSourceRecord
{
const char *generator_revision;
const char *input_digest;
const char *invocation_record;
const char *output_digest;
} generated_source_record_t;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
When an operation can be structured transactionally, evaluate rejectable input, range, permission, state, capacity, and resource preconditions before the first externally visible mutation. seL4's decode-then-invoke structure is a strong version of the same discipline.
If validation itself must mutate state or reserve a resource, document the rollback or one-way transition explicitly. Do not leave a half-applied operation because a check that could have run earlier failed later.
Contextual example:
Both callbacks are bound and validated before this fragment. The commit contract must define failure atomicity and exclude changes between validation and commit.
ret = validate_request(validation_context, request);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = commit_validated(commit_context, request);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Core modules and reusable libraries shall not write directly to stdout or stderr and shall not read interactive input from stdin unless their public contract is specifically a console interface. Route diagnostics through the project logging or callback port and return errors through the normal status contract.
This keeps libraries usable in firmware, daemons, GUIs, tests, services, and embedded hosts without an accidental process-global I/O policy.
Contextual example:
Consumer-owned callback. No process-wide stdout/stderr ownership or hidden formatting allocation; the logger binder states blocking/reentrancy and secret-redaction policy.
typedef int (*module_log_cb_t)(void *context, uint32_t event_id,
int operation_result);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Secrets that require erasure shall be cleared with a project primitive whose contract prevents the compiler from deleting the write as dead storage on supported toolchains. Plain memset(secret, 0, size) is not sufficient evidence when the object is dead immediately afterward.
Document which secret classes require erasure and the limits of software wiping for copies held in registers, caches, swap, crash dumps, DMA buffers, or other components.
Contextual example:
security-owned primitive; its adapter must provide and verify a non-elidable erase on the selected compiler/target. A callback name alone provides no erase guarantee.
ret = wipe_secret(security_context, secret, secret_size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A container or buffer expected to grow to a large size shall document whether growth requires relocating one contiguous allocation. In memory-constrained, latency- sensitive, or highly concurrent systems, consider segmented/chunked storage, bounded blocks, arenas, or another representation that avoids repeated large reallocations.
This is a representation decision, not a universal ban on contiguous arrays. Redpanda uses chunked containers for very large collections to avoid pathological contiguous growth; the same allocator-level concern applies to C containers.
Contextual example:
Private layout excerpt. Allocation, directory growth, lifetime and checked index translation remain owner contracts; this declaration does not implement a growable collection.
typedef struct SegmentDirectory
{
unsigned char **segments;
size_t segment_capacity_bytes;
size_t segment_count;
size_t directory_capacity;
} segment_directory_t;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Memory obtained from a request, packet, arena, pool, region, scratch allocator, or other scope-bound allocator shall not be retained beyond that allocator's documented lifetime. A pointer copied out of the scope remains borrowed; copying the pointer does not extend the allocation lifetime.
When data must survive the scope, copy the semantic value into storage owned by the longer-lived object or transfer ownership through an API that explicitly supports the operation. Wireshark's scoped wmem allocators are a mature example of binding bulk allocation lifetime to packet/file processing phases.
Contextual example:
The callback completes before arena reset and retains no pointer. Lifetime ends on the explicit reset even when the same address is later reused.
ret = consume_in_scope(consumer_context, &borrowed_view);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
A buffer API shall state whether its extent is measured in bytes, code units, characters, or elements; whether embedded zero bytes are valid; and whether a terminator is required, optional, or forbidden. Do not reuse a text API for arbitrary binary data merely because both happen to use char * at the ABI level.
Contextual example:
Contract header with <stddef.h>. A ByteView does not promise a NUL terminator or text encoding.
typedef struct ByteView
{
const unsigned char *data;
size_t size_bytes;
} byte_view_t;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A lockless protocol that requires one source-level load or store to remain one observable access shall use the project's reviewed READ_ONCE__/WRITE_ONCE__-style primitive or a C atomic operation with the required semantics. Plain access and volatile are not interchangeable substitutes for a concurrency contract.
The primitive must document size/alignment limits and what compiler transformations it prevents. It does not by itself provide ordering between separate accesses. Linux's READ_ONCE/WRITE_ONCE model motivates this separation.
Contextual example:
Inside the synchronization owner. published is initialized atomic_bool; a matching release publication establishes the intended visibility. Do not imitate kernel READ_ONCE with a plain non-atomic C object.
observed = atomic_load_explicit(&state->published, memory_order_acquire);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Ordinary business/module logic should call a named synchronization operation such as QUEUE_tryPush, STATE_publish, or REF_tryAcquire instead of constructing a multi-operation atomic protocol ad hoc at each call site. Low-level atomics remain appropriate inside the owner of that protocol.
QEMU follows a similar rule: locking and higher-level primitives are the default; bare atomics and barriers are reserved for reviewed performance-sensitive protocols.
Contextual example:
Consumer-owned port declaration. Its owner defines full/closed states, memory ordering, lifetime and bounded execution. The consumer does not invent an atomic protocol at the call site.
typedef int (*queue_try_push_cb_t)(void *context, const unsigned char *data,
size_t size_bytes);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Every standalone memory barrier/fence shall have a nearby comment that states what accesses it orders, which observer matters, and the operation on the other side that completes the ordering argument. “Required for ordering” is not enough.
Prefer synchronization primitives that embed the ordering when they express the contract. Linux requires source rationale for memory barriers in submitted patches.
Contextual example:
Synchronization-owner fragment. The one-shot payload is initialized before this store and not rewritten until a separate reuse protocol grants ownership.
/* Pairs with the consumer acquire-load before reading the payload. */ atomic_store_explicit(&slot->ready, true, memory_order_release);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Do not default every atomic operation to a full fence merely to avoid reasoning about ordering. Choose the weakest ordering that has a written invariant and passes the project's supported architecture tests; when that proof does not exist, use the approved conservative primitive rather than inventing a weaker one locally.
Any relaxed operation in a nontrivial protocol needs a comment or design reference that explains why relaxed ordering is sufficient.
Contextual example:
Synchronization-owner fragment: this statistic is not a publication signal and wraparound is explicitly acceptable or excluded by the counter contract. No unrelated data is synchronized.
atomic_fetch_add_explicit(&stats->completed, 1u, memory_order_relaxed);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A function that requires the caller to hold a specific lock must state that precondition in its declaration documentation and use the project's naming convention for locked helpers when one exists, for example cache_removeLocked. A wrapper that acquires the lock and a helper that assumes it is held must not share an ambiguous name. When the supported compiler/toolchain provides lock-requirement annotations, apply them as an additional machine-checkable contract; Open vSwitch uses this pattern for mutex and rwlock requirements.
QEMU uses _locked for this distinction; the exact suffix here remains governed by the project's naming rules.
Contextual example:
Internal-header declaration. The selected locking annotation, where supported, is provided by a compiler adapter; the suffix does not itself enforce locking.
/* Caller holds the cache lock for the complete operation. */ static int cache_removeLocked(cache_t *cache, uint32_t key);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
A floating value crossing a trust, file, network, sensor, or hardware boundary must have an explicit policy for NaN, positive/negative infinity, signed zero, and, where relevant, subnormal values. Validate with isfinite, isnan, or an equivalent project primitive before a finite-only physical or financial range check.
Do not use an ordinary numeric comparison as proof that a NaN has been rejected.
Contextual example:
Non-allocator module with <math.h>. ret and measurement are declared at entry. The target profile preserves the checks; do not combine this contract with flags that assume all inputs are finite.
if (!isfinite(measurement))
{
ret = -ERANGE;
goto function_output;
}
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
The existing volatile rule describes the semantics required inside a direct hardware-access implementation. Ordinary modules shall not scatter raw volatile T * register dereferences through business logic. Route register access through the platform/MMIO owner so width, ordering, read-clear/W1C behavior, reserved bits, trace hooks, fault injection, and test substitution have one contract.
OpenTitan's abs_mmio/sec_mmio split is a strong example of this boundary.
Contextual example:
Module-body fragment. The injected MMIO adapter owns register width, side effects, barriers and any volatile access.
ret = read_status(mmio_context, &status);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
When the physical threat model includes voltage, clock, electromagnetic, laser, or other fault injection, a security-critical state such as boot verification, debug unlock, lifecycle, or authorization may require an encoded representation with a deliberate Hamming-distance property instead of ordinary bool/small consecutive enum values.
Use a reviewed hardened-state abstraction; do not invent ad hoc magic constants in application code. This rule is profile-specific and does not replace ordinary boolean semantics outside the fault-resistance boundary. OpenTitan's hardened boolean/state primitives provide a concrete reference pattern. See CWE-1332 and CAPEC-624.
Contextual example:
Security-owned adapter with a declared fault model and invalid-codeword handling. Do not infer fault resistance from a larger enum or arbitrary hex constants.
ret = decode_hardened_state(security_context, encoded_state,
&authorization_state);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Writing the same C condition twice does not prove two independent machine-level checks exist. Redundant security checks intended to resist instruction skip or data faults shall use project hardening primitives that account for compiler optimization and shall be verified in the generated code for the supported hardened build.
Record the threat model and the failure response. Do not apply redundant-check patterns to ordinary code where they only add noise.
Contextual example:
The security adapter must verify generated-code properties of its redundant checks; merely repeating an if statement is not the implementation.
ret = verify_hardened_decision(security_context, decision);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
For a fault-sensitive sequence whose order or number of writes is security relevant, verify the expected sequence or side-effect count when the platform provides a credible mechanism. Checking only the final register value may miss an instruction skip, duplicate write, or omitted lock/unlock transition.
Keep the mechanism in the hardware/security owner. OpenTitan sec_mmio is a reference for this style of counted critical access.
Contextual example:
The hardware/security owner verifies required write count and order for its explicit fault model, not just final register values.
ret = verify_write_sequence(mmio_context, expected_sequence_id);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Related pitfalls:
Do not use ordinary memcmp as a cryptographic equality primitive when timing or early-exit behavior is observable. Use reviewed constant-time equality, hardened copy, and secure-erasure primitives whose compiler and fault behavior form part of the contract.
The primitive still needs length, bounds, alignment, and ownership validation before it executes.
Contextual example:
The constant-time primitive is supplied by a qualified security adapter. Inputs have validated lengths and lifetimes; this fragment makes no timing claim.
ret = compare_secret(security_context, left, right, size_bytes, &is_equal);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Every public API declaration needs enough documentation to use it without inspecting its implementation. Document units, nullability, ownership, lifetime, thread/ISR context, blocking behavior, error results, retained pointers, buffer extents, and any required call order that is not already obvious from the type system.
Non-obvious internal functions that depend on a lock state, hardware sequence, protocol phase, proof assumption, or unusual lifetime need the same contract at the point of declaration. Zephyr, seL4, OpenSSL, and HAProxy all treat API/contract comments as part of maintainability rather than optional decoration.
Contextual example:
Public contract excerpt. The documented guarantee must agree with all implementations and tests.
/* On failure, *read_bytes is zero and the buffer is unchanged. */
int STORAGE_read(storage_t *storage, unsigned char *buffer,
size_t capacity_bytes, size_t *read_bytes);
Class: PROJECT_POLICY. Apply the scope and requirement words below.
For a profile that claims safety, security, protocol, or externally specified behavior, each normative requirement shall have a stable identifier and an evidence path to one or more reviews, static checks, unit/integration tests, analysis results, or proof artifacts. Generated traceability must fail when a referenced control or verification artifact disappears.
SQLite's requirement/test extraction and seL4's configuration-specific proofs show two different but useful implementations of the same principle.
Contextual example:
Metadata shape. Every evidence path must name an actual executed or reviewed artifact and its configuration.
typedef struct VerificationLink
{
const char *requirement_id;
const char *control_id;
const char *test_id;
const char *evidence_artifact;
} verification_link_t;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
A lint, style, static-analysis, spelling, or prose checker implements a project rule; it does not silently redefine that rule. A heuristic diagnostic may be overridden by a reviewed deviation that names the control, tool diagnostic, rationale, scope, and owner. A checker false positive is fixed in configuration or suppression policy, not by distorting correct C merely to make the warning disappear.
Linux checkpatch explicitly expects maintainers to justify remaining exceptions.
Contextual example:
A diagnostic is resolved by fixing the code or by a scoped approved deviation. An empty deviation field does not itself grant permission.
typedef struct DiagnosticDisposition
{
const char *rule_id;
const char *tool_version;
const char *diagnostic_id;
const char *evidence_path;
const char *approved_deviation_id;
} diagnostic_disposition_t;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Code controlled by feature macros, architecture options, optional dependencies, word size, endianness, compiler family, sanitizer mode, or library backend shall be built and tested across the supported combinations that can change semantics. At minimum, test the configurations touched by a change and representative opposite values for new boolean feature switches.
Linux tests configuration combinations and multiple architectures; SQLite exercises multiple compilers/platforms; mature portable projects such as Git, FFmpeg, curl, PostgreSQL, and HAProxy keep compatibility paths buildable instead of assuming one developer workstation represents the product.
Contextual example:
Shell commands for the included example; repeat under the other approved configuration dimensions.
cmake -S examples -B build-c17 -DCMAKE_C_STANDARD=17 cmake --build build-c17 ctest --test-dir build-c17 --output-on-failure
Class: PROJECT_POLICY. Apply the scope and requirement words below.
A supported build configuration must not introduce compiler or linker warnings that are not covered by a documented deviation. CI should test more than one compiler family when the supported platform set includes them. Warnings in generated code or third-party imports need an owned suppression boundary rather than a global disable.
Contextual example:
CMake excerpt for the declared GCC/Clang hosted profile. Other toolchains need reviewed equivalent warning sets.
target_compile_options(sample_policy INTERFACE
-Wall -Wextra -Wpedantic -Werror
-Wdeclaration-after-statement)
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Code copied or vendored from another maintained project must record its upstream origin and update strategy. Avoid gratuitous local reformatting or semantic forks that make future security and bug-fix synchronization harder. If local rules require a wrapper or quarantine boundary, keep the imported implementation intact where practical and adapt it outside that boundary.
U-Boot explicitly preserves foreign subsystem style in selected imported code; nginx warns that copying private implementations can strand later security fixes.
Contextual example:
The record points to preserved upstream history and reviewed patches, not a guessed origin.
typedef struct ImportedSourceRecord
{
const char *upstream_repository;
const char *upstream_revision;
const char *local_patch_series;
const char *license_id;
} imported_source_record_t;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
The project may define named profiles such as general, analyzable, safety-critical, kernel, or formally-verified that prohibit constructs otherwise permitted by the base standard. A profile must list its additional restrictions and toolchain assumptions without changing the meaning of the base rules.
seL4 separates general, kernel, user-level, and verification-specific C constraints; FreeRTOS records project-wide and inline MISRA deviations for constraints that conflict with its embedded performance/footprint goals.
Contextual example:
Profile record, not a proof. A stricter verification profile does not silently redefine ordinary project C.
typedef struct VerificationProfile
{
const char *compiler_revision;
const char *language_subset;
const char *object_model;
const char *proof_artifact;
} verification_profile_t;
Class: PROJECT_POLICY. Apply the scope and requirement words below.
Normative Markdown and source comments are build inputs. CI shall check, as applicable, spelling, project acronyms, prose rules, malformed Markdown, unbalanced code fences, broken local anchors, duplicate control IDs, missing cross-document controls, trailing whitespace, and stale generated tables.
The checker configuration may allow technical vocabulary, identifiers, API names, standards names, CVE/CWE identifiers, and compact table cells without disabling the checks for the rest of the document. This follows the project's COIL-style textual validation model.
Contextual example:
Command entry point for the included validation tooling. Documentation examples and source files are cross-checked separately from compiler tests.
python3 examples/tools/validate.py --help
Class: PROJECT_POLICY. Apply the scope and requirement words below.
A user-facing error should identify the failed operation or constraint and the minimum safe context needed to fix it. Prefer “compression level must be 1 through 9” over “invalid argument” when the caller can act on that information. Do not reveal secrets or internal security state merely to make a message verbose.
HAProxy treats actionable user-facing diagnostics as a core quality property; the same rule improves firmware serviceability and incident response.
Contextual example:
Injected diagnostic port. Inputs are non-secret structured values; its failure must not overwrite the original operation error during cleanup.
ret = report_failure(log_context, operation_id, object_id, failure_code);
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A microarchitectural optimization shall record the target CPU/microarchitecture, compiler and relevant flags, representative workload, baseline, measurement method, and before/after result. When the claim concerns cache, TLB, branch, frontend, or memory-order behavior, include the relevant PMU/perf counters when available.
Do not accept source-level intuition as the only evidence for branchless code, prefetch, padding, forced inline, non-temporal stores, NUMA placement, or a custom atomic protocol.
Performance companion: CPERF-001. Apply each control within its stated scope.
Contextual example:
The harness fills every field from the run. This declaration contains no measured result.
typedef struct PerfRunIdentity
{
const char *source_revision;
const char *compiler_version;
const char *compiler_flags;
const char *target_cpu;
const char *workload_digest;
const char *raw_results_path;
} perf_run_identity_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Frequently modified state owned by different CPUs/threads should not share a cache line when profiling identifies coherence traffic as a limit. Separate read-mostly fields from write-hot fields and consider isolating a contended lock from unrelated mutable data.
Padding uses the target cache geometry, not an assumed universal constant. Linux false-sharing guidance and DPDK data-plane practice motivate this rule.
Performance companion: CPERF-010. Apply each control within its stated scope.
Contextual example:
Private per-owner state, including <stdint.h>. Only its owning thread writes it. Readers use a synchronized snapshot; this declaration alone provides no synchronization. The placement decision must also account for adjacent owner objects.
typedef struct OwnerCounters
{
uint64_t completed_count;
uint64_t failed_count;
} owner_counters_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
When two independent writers remain coupled after nominal cache-line separation, measure whether adjacent-line or spatial prefetch behavior still brings the neighbor line into the same cache hierarchy. Additional guard space is permitted only with measured benefit; do not blindly double every padding region.
Performance companion: CPERF-011. Apply each control within its stated scope.
Contextual example:
Illustrative private target profile with a 64-byte coherence unit, not a universal constant. Include <stdalign.h>, <stddef.h>, <stdint.h>. Storage must satisfy alignof(owner_slot_t); ordinary malloc is not assumed to provide this extended alignment. No remote unsynchronized reads/writes.
#define OPT_PROFILE_CACHE_LINE_BYTES ((size_t)(64U))
typedef struct OwnerSlot
{
alignas(OPT_PROFILE_CACHE_LINE_BYTES) uint64_t completed_count;
} owner_slot_t;
_Static_assert(sizeof(owner_slot_t) % OPT_PROFILE_CACHE_LINE_BYTES == 0u,
"array stride must preserve the measured isolation");
Class: PERFORMANCE. Apply the scope and requirement words below.
Write-hot counters, queues, caches, and statistics should be partitioned per CPU/ thread/lcore when the algorithm permits it, then aggregated at a lower frequency. Remote writes into another CPU's hot per-CPU state are discouraged because they can invalidate the owner's cache line and increase wake-up or service latency.
Performance companion: CPERF-013. Apply each control within its stated scope.
Contextual example:
Owning-thread fragment. local_count is retained in owner state; ret is local. flush is a validated injected callback; failure must mean no batch committed, otherwise retain explicit partial progress. Flush at deadline and shutdown too; batch size is not the only latency bound.
if (local_count == UINT64_MAX)
{
ret = -ERANGE;
goto function_output;
}
local_count++;
if (local_count >= flush_threshold)
{
ret = flush(owner_context, local_count);
if (ret != EXIT_SUCCESS)
goto function_output;
local_count = 0u;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Amortize locks, atomics, queue publication, allocator metadata updates, and I/O doorbell operations across a batch when throughput matters and the latency budget permits it. Batch size is part of the performance contract and must be benchmarked; it is not an arbitrary constant copied from another system.
Performance companion: CPERF-024. Apply each control within its stated scope.
Contextual example:
Owning-thread body. flush_batch must define one commit point and all-or-nothing failure here. Counters/queues define shutdown flush, maximum delay, overflow and fairness separately. A partial-success transport needs a progress field instead of this reset.
ret = flush_batch(owner_context, pending_count);
if (ret != EXIT_SUCCESS)
goto function_output;
pending_count = 0u;
Class: PERFORMANCE. Apply the scope and requirement words below.
On a measured coherence-bound path, avoid storing a shared value that is already in the desired state when a cheap read/test can prevent an ownership transition. The optimization must preserve atomicity and race semantics; a read-before-write is not a general substitute for synchronization.
Performance companion: CPERF-014. Apply each control within its stated scope.
Contextual example:
Inside a synchronization owner with exactly one writer. state is an initialized atomic telemetry value, not a publication flag and not a compare-and-swap transaction. observed is declared before validation. Do not apply this form where a repeated release store publishes new payload data.
observed = atomic_load_explicit(state, memory_order_relaxed);
if (observed != requested)
atomic_store_explicit(state, requested, memory_order_relaxed);
Class: PERFORMANCE. Apply the scope and requirement words below.
For read-dominated structures, evaluate RCU, sequence counters, immutable snapshots, epoch/hazard schemes, or another design that keeps the common reader path from writing shared cache lines. A reference count on every read can turn a logically read-only workload into a coherence bottleneck.
Sequence counters are not valid for data containing pointers that a writer can invalidate unless a separate lifetime scheme makes those pointers safe.
Performance companion: CPERF-026. Apply each control within its stated scope.
Contextual example:
Function-tail fragment. ret and snapshot are declared and initialized at entry. Validated callbacks implement retention/reclamation, and release_snapshot is infallible. A retry counter or read-only access alone does not protect pointed-to objects.
ret = acquire_snapshot(snapshot_context, &snapshot);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = lookup(snapshot_context, snapshot, key, out);
function_output : if (snapshot != (const snapshot_t *)(NULL))
{
release_snapshot(snapshot_context, snapshot);
}
return ret;
Class: PERFORMANCE. Apply the scope and requirement words below.
A feature that is almost always disabled on a critical hot path may use a platform static-key/patchable-branch facility when the update frequency is low and the target supports it. Keep runtime text modification, instruction-cache synchronization, and cross-CPU update costs inside a platform adapter and benchmark both steady-state and toggle cost.
Performance companion: CPERF-032. Apply each control within its stated scope.
Contextual example:
feature_is_enabled is an infallible read-only predicate from a bound port. A platform implementation may use a static key only under its approved patching, lifetime and I-cache synchronization contract. The ordinary module performs no text patching.
if (feature_is_enabled(feature_context))
{
ret = trace(trace_context, event);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
always_inline/forced-inline annotations are prohibited by default. Permit them when required by a low-level ABI/instruction constraint, when compile-time constants remove most of the body, or when profiling shows a repeatable benefit. Include I-cache and uop-cache/code-size effects in the review; fewer calls can still execute slower code.
This does not change the existing allowance for small static inline type-safe wrappers in headers.
Performance companion: CPERF-029. Apply each control within its stated scope.
Contextual example:
Small module-local helper using <stddef.h>. The infallible accessor return-type exception permits size_t ret but not extra exits. No forced-inline attribute is used; inspect code size and target results before adding one.
static inline size_t opt_minSize(size_t left, size_t right)
{
size_t ret = 0u;
ret = left < right ? left : right;
goto function_output;
function_output:
return ret;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Loop unrolling, template-like macro expansion, duplicated specialization, and manual inlining shall be evaluated for instruction-cache and decoded-uop-cache footprint, not only dynamic instruction count. Split genuinely cold error paths out of a hot region when profiles show frontend pressure.
Performance companion: CPERF-028. Apply each control within its stated scope.
Contextual example:
Run on the produced executable, together with the representative workload and target front-end events. Byte count alone is not a throughput measurement.
size build-release/tests_static objdump -d build-release/tests_static > tests-static.disassembly.txt
Class: PERFORMANCE. Apply the scope and requirement words below.
Do not replace a predictable branch with conditional moves, mask arithmetic, or branchless table logic by default. Branchless code can lengthen dependency chains and execute work that speculation would have skipped. Use branchless forms when profile data shows the branch is sufficiently unpredictable and the transformed work is cheaper on the target.
Performance companion: CPERF-030. Apply each control within its stated scope.
Contextual example:
Function-body fragment with validated inputs and entry-declared selected. Compare it with selected = left < right ? left : right under the same contract. Neither C syntax guarantees branch or cmov machine code.
if (left < right)
selected = left;
else
selected = right;
Class: PERFORMANCE. Apply the scope and requirement words below.
likely/unlikely, hot/cold attributes, and equivalent compiler hints need a stable probability assumption or profile evidence. Review the generated layout because the main effect may be code placement and I-cache behavior rather than dynamic predictor accuracy.
Performance companion: CPERF-031. Apply each control within its stated scope.
Contextual example:
OPT_UNLIKELY__ is a project compiler-adapter macro with a plain-expression fallback and single evaluation. Use only for a measured stable rare path; the probability is not guessed from the name. ret was assigned outside the condition.
if (OPT_UNLIKELY__(ret != EXIT_SUCCESS))
goto function_output;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A manual prefetch shall identify the target data, prefetch distance, expected reuse, and independent work between prefetch and demand use. Measure cache pollution, MSHR/ fill-buffer pressure, TLB/page-walk pressure, and memory bandwidth. Remove a prefetch that arrives too late, evicts useful data, or adds traffic to an already bandwidth- bound workload.
Compiler movement of prefetch instructions can change the result; compare generated code when compiler/version is part of the measured dependency.
Performance companion: CPERF-035. Apply each control within its stated scope.
Contextual example:
Entry-declared index/distance/ret; validated callbacks and full array extent. prefetch is infallible and must not retain the pointer. distance is selected by a measured profile; subtraction is safe because index < item_count. Measure pollution and bandwidth, not just demand misses.
for (index = 0u; index < item_count; index++)
{
if (distance < item_count - index)
prefetch(prefetch_context, &items[index + distance]);
ret = consume(consume_context, &items[index]);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
When a hot loop is latency-bound and has independent items, overlap demand/prefetch latency with useful work on other items rather than immediately consuming a just- prefetched address. DPDK packet pipelines use this pattern extensively.
Performance companion: CPERF-035. Apply each control within its stated scope.
Contextual example:
Entry-declared index/distance/ret; validated callbacks and full array extent. prefetch is infallible and must not retain the pointer. distance is selected by a measured profile; subtraction is safe because index < item_count. Measure pollution and bandwidth, not just demand misses.
for (index = 0u; index < item_count; index++)
{
if (distance < item_count - index)
prefetch(prefetch_context, &items[index + distance]);
ret = consume(consume_context, &items[index]);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
For measured hot wide accesses, align data so the common load/store does not straddle the target's costly cache-line or vector boundary. Do not add large alignment to all objects without measuring the memory-footprint tradeoff.
Performance companion: CPERF-019. Apply each control within its stated scope.
Contextual example:
Target-profile declaration. The vector alignment comes from the selected backend and allocation contract. Capacity 256 is an illustrative private block size, not a performance claim. Tail handling must remain within the real object extent.
typedef struct PrivateVectorBlock
{
alignas(OPT_PROFILE_VECTOR_ALIGNMENT) unsigned char bytes[256];
} private_vector_block_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
An atomic/locked operand shall not intentionally straddle a hardware cache-line boundary on targets where that can become a split lock or bus lock. Assert or encode alignment in the owning type when the primitive requires it.
Performance companion: CPERF-012. Apply each control within its stated scope.
Contextual example:
Private target-specific declaration using <stdatomic.h> and <stdalign.h>. OPT_PROFILE_CACHE_LINE_BYTES is supplied by an approved measured profile. Initialize atomic flags before publication; alignment, fairness and wait policy remain separate obligations.
typedef struct PrivateLockLayout
{
alignas(OPT_PROFILE_CACHE_LINE_BYTES) atomic_flag first_lock;
alignas(OPT_PROFILE_CACHE_LINE_BYTES) atomic_flag second_lock;
} private_lock_layout_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When PMU data reports store-forwarding stalls, inspect preceding stores before modifying the dependent load. Small stores followed immediately by wider or partially overlapping loads, mismatched alignment, or non-contained regions can defeat forwarding on common out-of-order CPUs.
Do not contort portable code around one microarchitecture without a specialized implementation and benchmark evidence.
Performance companion: CPERF-016. Apply each control within its stated scope.
Contextual example:
Local representation example: include <stdint.h>/<string.h>; uint32_t word is declared at function entry. bytes is valid disjoint storage for sizeof(word) bytes, replacement is uint8_t, and the intended operation changes the least-significant eight value bits in native representation. Inspect generated code; this is not portable external byte-order decoding and it does not promise a forwarding improvement.
memcpy(&word, bytes, sizeof(word)); word = (word & UINT32_C(0xFFFFFF00)) | (uint32_t)replacement; memcpy(bytes, &word, sizeof(word));
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When memory-disambiguation counters show false dependencies, inspect independent hot load/store addresses with identical page offsets. Adjust allocation/layout only after proving a 4 KiB alias effect on the target; equal low address bits are not a general C bug.
Performance companion: CPERF-017. Apply each control within its stated scope.
Contextual example:
Harness callbacks collect real addresses/layout on a declared platform. Pointer ordering or subtraction between unrelated objects is not used. Compare equal/different low page offsets only inside the platform measurement adapter.
/* Read actual layout and PMU events; do not change buffer alignment blindly. */
ret = record_layout(layout_context, source, destination, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = run_variant(benchmark_context, source, destination, size_bytes);
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A NUMA-sensitive hot path should treat thread/CPU affinity, memory placement, IRQ routing, device locality, and write-hot ownership as one placement problem. Do not move execution to a remote node while leaving its dominant memory or device traffic behind without measuring remote-access cost.
Performance companion: CPERF-020. Apply each control within its stated scope.
Contextual example:
In-process DTO using <stdint.h>. A single runtime/platform owner applies and verifies the plan. The IDs are platform identifiers; equal numeric IDs across the fields do not imply locality.
typedef struct PlacementPlan
{
uint32_t cpu_id;
uint32_t memory_node_id;
uint32_t irq_cpu_id;
uint32_t device_node_id;
} placement_plan_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Kernel/runtime code that owns mappings shall invalidate the smallest correct virtual range and CPU set supported by the platform. Avoid high-frequency map/unmap or protection churn in hot algorithms when stable mappings satisfy the same security and lifetime contract.
Performance companion: CPERF-022. Apply each control within its stated scope.
Contextual example:
Privileged platform-owner fragment with a validated callback. The adapter computes the complete required CPU set and address range and supplies architecture-required barriers. Ordinary module code never omits a required remote invalidation for speed.
ret = invalidate_range(address_space_context, start_page, page_count,
participating_cpu_set);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When page-walk/DTLB counters dominate, reduce translation working set, improve page locality, or evaluate larger pages according to the OS/target policy. Good L1/L2 data locality does not prove the address-translation path is efficient.
Performance companion: CPERF-021. Apply each control within its stated scope.
Contextual example:
Harness record using <stddef.h>/<stdint.h>. Populate with target-defined PMU events and measured elapsed time. A missing PMU capability is recorded as unavailable, not as a zero result.
typedef struct TranslationEvidence
{
size_t page_size_bytes;
size_t mapped_bytes;
uint64_t page_walk_count;
uint64_t tlb_miss_count;
uint64_t elapsed_ns;
} translation_evidence_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When LLC/cache conflict misses remain high despite adequate nominal capacity, an allocator or OS profile may investigate cache-set placement, coloring, or equivalent mapping controls. Do not expose page coloring to ordinary modules or assume one cache indexing function across processors.
Performance companion: CPERF-023. Apply each control within its stated scope.
Contextual example:
An allocator-level experiment record. Physical placement or cache hashing must not be inferred from portable pointer bits. Keep a baseline, working set and byte consumption comparable.
typedef struct PlacementExperiment
{
size_t allocation_stride_bytes;
size_t working_set_bytes;
uint32_t allocator_variant_id;
const char *cache_event_record;
} placement_experiment_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Use non-temporal/write-combining stores only for measured large streaming writes with little near-term reuse where cache pollution is harmful. Keep a normal-store fallback and benchmark crossover sizes. Before publishing completion to another CPU or device, apply the architecture-defined ordering/fence required for the non-temporal path.
Performance companion: CPERF-037. Apply each control within its stated scope.
Contextual example:
Platform-owner sequence through validated callbacks. complete_stores supplies target/device completion and ordering, not merely a compiler barrier. Do not publish on either preceding failure. The backend defines aliasing, alignment, profitable-size threshold and cached fallback.
ret = stream_copy(stream_context, destination, source, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = complete_stores(stream_context);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = publish_ready(publication_context);
Class: PERFORMANCE. Apply the scope and requirement words below.
Where the hardware write-combining model and algorithm permit it, complete a full cache-line stream before interleaving many partially written lines. Partial WC buffers can increase transactions or force read-modify-write behavior. This rule is strictly target/profile gated.
Performance companion: CPERF-038. Apply each control within its stated scope.
Contextual example:
Entry declarations and validation precede this body; line_bytes is nonzero and cursor names the remaining span. Callbacks must not overrun it. Tail code must not round the logical length up into unowned bytes. Publication follows the platform completion protocol.
while (remaining_bytes >= line_bytes)
{
ret = write_line(stream_context, cursor, line_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
cursor += line_bytes;
remaining_bytes -= line_bytes;
}
if (remaining_bytes != 0u)
ret = write_tail(stream_context, cursor, remaining_bytes);
Class: PERFORMANCE. Apply the scope and requirement words below.
A data-plane/ISR/ultra-low-latency profile may prohibit general-purpose libc routines in its hot path when measured implementations have unsuitable latency, code size, or branch behavior. DPDK specifically warns against general libc memcpy/strcpy in its data plane. Such a profile must provide reviewed replacements and correctness tests; it does not change the standard-library policy for ordinary code.
Performance companion: CPERF-025. Apply each control within its stated scope.
Contextual example:
Consumer-owned port declaration. Its owner defines full/closed states, memory ordering, lifetime and bounded execution. The consumer does not invent an atomic protocol at the call site.
typedef int (*queue_try_push_cb_t)(void *context, const unsigned char *data,
size_t size_bytes);
Class: PERFORMANCE. Apply the scope and requirement words below.
When an algorithm has handwritten SIMD, assembly, JIT, intrinsic, or other target- specific implementation, keep an independent portable C implementation when practical. The portable version is the semantic oracle, debugging fallback, and unsupported-target implementation; do not let the optimized implementation define its own expected result.
FFmpeg checkasm and OpenSSL processor-specific code follow this model.
Performance companion: CPERF-005. Apply each control within its stated scope.
Contextual example:
Include <stddef.h>, <stdlib.h>, <errno.h> and an own header declaring the function. data names size_bytes readable bytes; count_out is disjoint writable storage. No ownership transfer. Zero length requires a valid pointer. This is a scalar reference, not an optimized backend.
int OPT_countByteReference(const unsigned char *data, size_t size_bytes,
unsigned char needle, size_t *count_out)
{
int ret = EXIT_SUCCESS;
size_t count = 0u;
size_t index = 0u;
if ((data == (const unsigned char *)(NULL)) ||
(count_out == (size_t *)(NULL)))
{
ret = -EINVAL;
goto function_output;
}
for (index = 0u; index < size_bytes; index++)
{
if (data[index] == needle)
count++;
}
*count_out = count;
function_output:
return ret;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Compare every specialized backend against the reference across boundary values, misalignment permitted by contract, random/fuzz inputs, error cases, and supported ISA feature levels. The test shall also prove that the intended backend executed; a correct result from an accidental fallback is not coverage of the optimized path.
Performance companion: CPERF-006. Apply each control within its stated scope.
Contextual example:
Test-body fragment. Declare ret, expected and actual at entry; validate both callbacks and their contexts. Repeat over the allowed length, alignment and aliasing matrix. Matching one output does not prove general equivalence.
ret = reference(reference_context, data, size_bytes, &expected);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = candidate(candidate_context, data, size_bytes, &actual);
if (ret != EXIT_SUCCESS)
goto function_output;
if (actual != expected)
{
ret = -EDOM;
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Detect CPU/ISA features in one owned dispatch layer, bind a function table or stable operation pointer, and keep feature tests out of the inner algorithm loop. Callers consume the semantic operation contract, not AVX/NEON/SVE/RVV-specific names.
Performance companion: CPERF-007. Apply each control within its stated scope.
Contextual example:
Consumer-owned in-process port. Include <stddef.h> and <stdint.h>. The composition owner validates ISA/OS prerequisites and publishes a complete table; the table and context remain stable during calls.
typedef int (*opt_count_cb_t)(void *context, const unsigned char *data,
size_t size_bytes, size_t *count_out);
typedef struct OptDispatch
{
void *context;
opt_count_cb_t count;
uint32_t selected_backend_id;
} opt_dispatch_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
SVE, RVV, or another variable-vector-length implementation shall be tested at multiple supported vector lengths, including the minimum and representative larger lengths. Passing on one processor does not prove a vector-length-agnostic algorithm.
Performance companion: CPERF-040. Apply each control within its stated scope.
Contextual example:
Harness fragment with entry-declared IDs and ret. selected_backend reports the implementation that will execute; unsupported hardware is not silently counted as passing the optimized test.
ret = selected_backend(dispatch_context, &actual_backend_id);
if (ret != EXIT_SUCCESS)
goto function_output;
if (actual_backend_id != requested_backend_id)
{
ret = -ENOTSUP;
goto function_output;
}
ret = differential_test(test_context);
Class: PERFORMANCE. Apply the scope and requirement words below.
If a JIT, translation block, cached execution plan, or specialized hot path removes a runtime check because configuration is treated as invariant, the owner shall define which state changes invalidate that specialization and how invalidation is synchronized. QEMU TCG is a mature example: translated code is specialized against CPU/code state and invalidated when the underlying assumption changes.
Performance companion: CPERF-008. Apply each control within its stated scope.
Contextual example:
Externally synchronized owner fragment. Generation changes cover every assumed invariant; wrap/reuse is prohibited while an older artifact may exist. invalidate, bind and execute are validated owner callbacks. Rebinding must not publish a partial artifact.
if (cached_generation != current_generation)
{
ret = invalidate(cache_context);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = bind(cache_context, current_generation);
if (ret != EXIT_SUCCESS)
goto function_output;
}
ret = execute(cache_context);
Class: PERFORMANCE. Apply the scope and requirement words below.
In JIT/code-generation or aggressively specialized paths, prefer an out-of-line helper for rare complex operations when inlining would materially increase generated code, translation time, or frontend footprint. QEMU TCG explicitly recommends helpers for seldom-used instructions whose inline IR becomes large; the exact crossover remains a measurement, not a fixed project constant.
Performance companion: CPERF-009. Apply each control within its stated scope.
Contextual example:
Function-body fragment after validation. Both operations are bound callbacks or helpers owned by this module. Moving the uncommon operation out of line requires generated-code and workload evidence.
if (has_exceptional_opcode)
{
ret = cold_operation(operation_context, request, reply);
goto function_output;
}
ret = common_operation(operation_context, request, reply);
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When a hot loop is limited by indirect-branch/BTB behavior, stabilize dispatch targets outside the inner loop where the semantics permit it. Do not manually devirtualize or cache a callback target if binding can change concurrently without an invalidation or synchronization contract.
Performance companion: CPERF-033. Apply each control within its stated scope.
Contextual example:
Declare process, process_context, index and ret at entry, with typed NULL for pointers. Validate the table, mandatory callback and item extent before this fragment. The binder prevents replacement/unload for the entire loop. This is not permission to bypass callback instrumentation.
process = callbacks->process;
process_context = callbacks->process_context;
for (index = 0u; index < item_count; index++)
{
ret = process(process_context, &items[index]);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
RSB/return-prediction pressure is a profiling diagnosis, not a source-level recursion limit. If a frontend-bound hot path shows return misprediction or excessive tiny call chains, evaluate outlining/inlining with generated-code and stack measurements rather than imposing a universal call-depth threshold.
Performance companion: CPERF-028. Apply each control within its stated scope.
Contextual example:
Run on the produced executable, together with the representative workload and target front-end events. Byte count alone is not a throughput measurement.
size build-release/tests_static objdump -d build-release/tests_static > tests-static.disassembly.txt
Class: PERFORMANCE. Apply the scope and requirement words below.
Kernel/hypervisor benchmarks shall record relevant speculation mitigations, firmware/ microcode level, and security mode when those settings can alter indirect branches, returns, barriers, or cross-domain transitions. Results collected with materially different mitigation state are not directly comparable without that qualification.
Performance companion: CPERF-002. Apply each control within its stated scope.
Contextual example:
Record the effective settings, not only the intended launch options. Include <stdbool.h>.
typedef struct PerfMachinePolicy
{
const char *kernel_release;
const char *cpu_affinity;
const char *numa_policy;
const char *governor;
const char *mitigation_state;
const char *hardware_prefetch_policy;
bool smt_enabled;
} perf_machine_policy_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
AutoFDO, Propeller, PGO, basic-block reordering, hot/cold partitioning, or manual code layout shall use a profile representative of the deployment workload. Record profile provenance and verify that the optimized binary improves the intended workload without regressing mandatory latency or safety tests.
Performance companion: CPERF-003. Apply each control within its stated scope.
Contextual example:
Keep training and independent evaluation inputs distinct. The fields are metadata, not evidence that a profile is representative.
typedef struct PerfProfileIdentity
{
const char *training_input_digest;
const char *deployment_workload_class;
const char *compiler_build_id;
const char *profile_digest;
const char *refresh_trigger;
} perf_profile_identity_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
For very large growable collections in long-lived services, benchmark segmented or chunked storage when contiguous reallocation, allocator fragmentation, or latency spikes dominate. Keep the representation behind the owning container API so ordinary callers do not depend on segmentation. Redpanda's chunked_vector/ chunked_hash_map policy is a useful systems-scale example, even though Redpanda is C++ rather than C.
Performance companion: CPERF-023. Apply each control within its stated scope.
Contextual example:
Private storage-layout excerpt with <stddef.h>. The owner checks segment and offset arithmetic, manages directory growth, and documents pointer stability. Compare this layout to contiguous storage under the actual workload; it does not prove a performance gain.
typedef struct SegmentedBytes
{
unsigned char **segments;
size_t segment_size_bytes;
size_t segment_count;
size_t directory_capacity;
} segmented_bytes_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
On an out-of-order target, a hot loop that retires many stores can become limited by store-buffer occupancy, ownership traffic, or delayed writeback even when the stored values are not on the arithmetic critical path. Remove stores that do not change observable state, aggregate updates when the latency contract permits it, and confirm the diagnosis with target PMU counters rather than source-level store counts alone.
Performance companion: CPERF-018. Apply each control within its stated scope.
Contextual example:
Owner-local accumulation before one output write. sum and index are entry declarations. checked_add is a validated callback with in-place output permitted. No observer may require an intermediate store, and out must not overlap unread samples.
for (index = 0u; index < sample_count; index++)
{
ret = checked_add(sum, samples[index], &sum);
if (ret != EXIT_SUCCESS)
goto function_output;
}
*out = sum;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A performance change that alters stride, adjacency, page traversal, or software prefetch shall account for the target's hardware prefetchers. Adjacent-line and next-page behavior can fetch data or translations that the program never consumes, while a useful hardware stream can make an added software prefetch redundant. Measure cache pollution, bandwidth, TLB/page-walk activity, and miss latency with the relevant prefetch configuration when the platform exposes it.
Prefetching a miss path or otherwise fetching data that may not be consumed is allowed only when measurement shows that smoother control flow or latency hiding outweighs the extra traffic.
Performance companion: CPERF-047. Apply each control within its stated scope.
Contextual example:
An actual A/B measurement record supplied by the target owner. Never change system-wide prefetch policy from ordinary library code or claim unsupported PMU counters are zero.
typedef struct PrefetchExperiment
{
const char *effective_hardware_policy;
size_t software_distance_items;
const char *cache_events;
const char *translation_events;
const char *bandwidth_events;
} prefetch_experiment_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When a DMA engine, PCIe device, DDIO path, or write-combining interface benefits from full-line transfers, organize measured streaming buffers so common writes complete the target cache line instead of repeatedly touching partial lines. This rule applies only when the device/cache-coherency contract documents the relevant transaction geometry; it does not authorize padding or writing bytes outside the owned buffer.
Performance companion: CPERF-036. Apply each control within its stated scope.
Contextual example:
A platform-owner descriptor, not a wire format. Include <stddef.h>/<stdint.h>. The mapping contract defines actual alignment, coherency, cache maintenance, permitted cache-line rounding and ownership handover. used_bytes never authorizes stores into adjacent allocations.
typedef struct DmaBufferView
{
unsigned char *data;
size_t capacity_bytes;
size_t used_bytes;
uint32_t mapping_id;
} dma_buffer_view_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Independent locks or atomic state machines that are acquired by different CPUs shall not be deliberately packed into one word or cache line when profiling shows coherence contention. Logical independence is not enough: bit-packing several locks can force unrelated CPUs to exchange ownership of the same line. Isolate the measured hot locks without turning cache-line padding into a global structure-layout rule.
Performance companion: CPERF-012. Apply each control within its stated scope.
Contextual example:
Private target-specific declaration using <stdatomic.h> and <stdalign.h>. OPT_PROFILE_CACHE_LINE_BYTES is supplied by an approved measured profile. Initialize atomic flags before publication; alignment, fairness and wait policy remain separate obligations.
typedef struct PrivateLockLayout
{
alignas(OPT_PROFILE_CACHE_LINE_BYTES) atomic_flag first_lock;
alignas(OPT_PROFILE_CACHE_LINE_BYTES) atomic_flag second_lock;
} private_lock_layout_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Manual function, loop, basic-block, or patch-site alignment requires a target-specific reason and generated-code evidence. Frontend fetch/decode boundaries, decoded-uop caches, branch errata, and runtime text patching can make placement matter, but the useful boundary varies by CPU. A patchable instruction sequence shall also satisfy the platform's atomicity and instruction-cache synchronization contract and shall not straddle a forbidden patch boundary.
Performance companion: CPERF-034. Apply each control within its stated scope.
Contextual example:
Commands on a built ELF test binary. A target owner may compare PGO/layout variants, but no arbitrary alignment threshold is asserted here.
# Inspect the final text layout for the actual optimized build. readelf -S build-release/tests_static objdump -d build-release/tests_static > final-layout.txt
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Do not treat a compare-and-swap, fetch-add, or locked RMW as having one architecture-wide constant cost. Its latency and throughput depend on cache-line ownership, socket/NUMA placement, contenders, memory ordering, and interconnect topology. Benchmark the operation under the intended sharing pattern; prefer ownership partitioning or batching before introducing a more elaborate global atomic protocol.
Performance companion: CPERF-024. Apply each control within its stated scope.
Contextual example:
Owning-thread body. flush_batch must define one commit point and all-or-nothing failure here. Counters/queues define shutdown flush, maximum delay, overflow and fairness separately. A partial-success transport needs a progress field instead of this reset.
ret = flush_batch(owner_context, pending_count);
if (ret != EXIT_SUCCESS)
goto function_output;
pending_count = 0u;
These recovered controls are kept distinct from local C syntax and safety rules. The original file name was c_performance.md; its contents are integrated here so the delivered set remains three normative/reference documents. CPERF IDs retain their meanings. CSTYLE-201 through CSTYLE-242 above preserve the earlier performance branch and link to the corresponding later CPERF controls.
MUST applies in the rule's stated scope. SHOULD needs a measured reason when a technique is relevant. MAY permits an experiment. Profile-gated techniques require a named target and representative measured workload; they are not enabled merely because this document includes an example. Correctness, ownership and the selected project conventions take precedence.
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A microarchitectural optimization must identify:
The change must state the hypothesis before interpreting the measurements. Wall-clock improvement without a reproducible workload does not establish a microarchitectural rule.
Contextual example:
The harness fills every field from the run. This declaration contains no measured result.
typedef struct PerfRunIdentity
{
const char *source_revision;
const char *compiler_version;
const char *compiler_flags;
const char *target_cpu;
const char *workload_digest;
const char *raw_results_path;
} perf_run_identity_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Performance baselines must record machine policy that changes execution cost, including applicable speculation mitigations, simultaneous multithreading, frequency policy, NUMA policy, transparent huge pages, page size, and interrupt placement. Results produced under different policies must not be compared as if they came from the same configuration.
Contextual example:
Record the effective settings, not only the intended launch options. Include <stdbool.h>.
typedef struct PerfMachinePolicy
{
const char *kernel_release;
const char *cpu_affinity;
const char *numa_policy;
const char *governor;
const char *mitigation_state;
const char *hardware_prefetch_policy;
bool smt_enabled;
} perf_machine_policy_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Profile-guided optimization, hot/cold layout, and branch-frequency controls must use profiles representative of the deployment workload. The profile artifact must have an owner, generation recipe, input description, compiler compatibility policy, and refresh trigger.
LLVM documents PGO as optimization based on how a program runs. A profile produced by a different workload is evidence for that workload, not for the intended deployment.llvm-pgo
Contextual example:
Keep training and independent evaluation inputs distinct. The fields are metadata, not evidence that a profile is representative.
typedef struct PerfProfileIdentity
{
const char *training_input_digest;
const char *deployment_workload_class;
const char *compiler_build_id;
const char *profile_digest;
const char *refresh_trigger;
} perf_profile_identity_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Benchmark success must not replace:
An optimization that makes a defect harder to reproduce is not a correction.
Contextual example:
Inside the review harness: ret and flags are declared at function entry. review_measurements is an injected callback, validated before this fragment; it does not create correctness evidence.
if (!correctness_passed || !backend_equivalence_passed)
{
ret = -EINVAL;
goto function_output;
}
ret = review_measurements(review_context, measurements);
Class: PERFORMANCE. Apply the scope and requirement words below.
Every architecture-specific or generated optimized implementation should retain an independent portable C reference when practical. The reference defines observable behavior and edge cases; the optimized implementation does not act as its own oracle.
The reference must not share the same low-level algorithm fragment when that sharing could reproduce the same defect in both implementations.
Contextual example:
Include <stddef.h>, <stdlib.h>, <errno.h> and an own header declaring the function. data names size_bytes readable bytes; count_out is disjoint writable storage. No ownership transfer. Zero length requires a valid pointer. This is a scalar reference, not an optimized backend.
int OPT_countByteReference(const unsigned char *data, size_t size_bytes,
unsigned char needle, size_t *count_out)
{
int ret = EXIT_SUCCESS;
size_t count = 0u;
size_t index = 0u;
if ((data == (const unsigned char *)(NULL)) ||
(count_out == (size_t *)(NULL)))
{
ret = -EINVAL;
goto function_output;
}
for (index = 0u; index < size_bytes; index++)
{
if (data[index] == needle)
count++;
}
*count_out = count;
function_output:
return ret;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
SIMD, assembly, accelerator, JIT, and architecture-tuned implementations must be differential-tested against the portable reference across:
FFmpeg's checkasm infrastructure exposes CPU-feature selection and compares optimized functions under controlled CPU flags.ffmpeg-checkasm
Contextual example:
Test-body fragment. Declare ret, expected and actual at entry; validate both callbacks and their contexts. Repeat over the allowed length, alignment and aliasing matrix. Matching one output does not prove general equivalence.
ret = reference(reference_context, data, size_bytes, &expected);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = candidate(candidate_context, data, size_bytes, &actual);
if (ret != EXIT_SUCCESS)
goto function_output;
if (actual != expected)
{
ret = -EDOM;
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Callers must use one algorithm contract. A dedicated dispatch layer selects the portable or specialized backend after validating CPU, operating-system, device, alignment, and feature prerequisites.
Dispatch tests must prove which backend executed. Correct output alone does not prove that the intended implementation was selected.
Contextual example:
Consumer-owned in-process port. Include <stddef.h> and <stdint.h>. The composition owner validates ISA/OS prerequisites and publishes a complete table; the table and context remain stable during calls.
typedef int (*opt_count_cb_t)(void *context, const unsigned char *data,
size_t size_bytes, size_t *count_out);
typedef struct OptDispatch
{
void *context;
opt_count_cb_t count;
uint32_t selected_backend_id;
} opt_dispatch_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Cached code, execution plans, or function bindings may omit repeated checks only when their assumed state has an explicit invalidation contract. The contract must identify:
QEMU records CPU state in a Translation Block and stops reusing that block when the state no longer matches.qemu-tcg
Contextual example:
Externally synchronized owner fragment. Generation changes cover every assumed invariant; wrap/reuse is prohibited while an older artifact may exist. invalidate, bind and execute are validated owner callbacks. Rebinding must not publish a partial artifact.
if (cached_generation != current_generation)
{
ret = invalidate(cache_context);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = bind(cache_context, current_generation);
if (ret != EXIT_SUCCESS)
goto function_output;
}
ret = execute(cache_context);
Class: PERFORMANCE. Apply the scope and requirement words below.
Rare or complex functionality should not inflate a hot generated-code or inner dispatch path merely to avoid a call. QEMU recommends C helpers for complicated or seldom-used guest instructions and documents an approximate historical threshold rather than treating expansion as automatically faster.qemu-ops
The project must choose the boundary through measurement; no fixed instruction count applies to all targets.
Contextual example:
Function-body fragment after validation. Both operations are bound callbacks or helpers owned by this module. Moving the uncommon operation out of line requires generated-code and workload evidence.
if (has_exceptional_opcode)
{
ret = cold_operation(operation_context, request, reply);
goto function_output;
}
ret = common_operation(operation_context, request, reply);
Class: PERFORMANCE. Apply the scope and requirement words below.
Frequently modified state should have one CPU, thread, shard, or device owner when the architecture permits it. Other execution contexts should send work to that owner or update separate local state instead of repeatedly transferring exclusive ownership of one cache line.
Contextual example:
Private per-owner state, including <stdint.h>. Only its owning thread writes it. Readers use a synchronized snapshot; this declaration alone provides no synchronization. The placement decision must also account for adjacent owner objects.
typedef struct OwnerCounters
{
uint64_t completed_count;
uint64_t failed_count;
} owner_counters_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Fields written by independent execution contexts should not share a cache line after perf c2c, an equivalent coherence profiler, or target counters prove harmful false sharing. Layout review should:
Linux documents these patterns and recommends evidence-based balancing of speed, complexity, and space.linux-false-sharing
One cache line of separation is not a portable constant. Adjacent-line prefetchers and different cache geometries can require a target-specific guard.
Contextual example:
Illustrative private target profile with a 64-byte coherence unit, not a universal constant. Include <stdalign.h>, <stddef.h>, <stdint.h>. Storage must satisfy alignof(owner_slot_t); ordinary malloc is not assumed to provide this extended alignment. No remote unsynchronized reads/writes.
#define OPT_PROFILE_CACHE_LINE_BYTES ((size_t)(64U))
typedef struct OwnerSlot
{
alignas(OPT_PROFILE_CACHE_LINE_BYTES) uint64_t completed_count;
} owner_slot_t;
_Static_assert(sizeof(owner_slot_t) % OPT_PROFILE_CACHE_LINE_BYTES == 0u,
"array stride must preserve the measured isolation");
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A lock must not automatically share a cache line with the data it protects. If many waiters poll or modify the lock while the owner writes protected data, the combined layout can increase coherence traffic. Lock placement requires the same measurement and ownership analysis as other write-hot state.
Do not pack logically independent hot locks into bits of one word or into one cache line merely to save memory.
Contextual example:
Private target-specific declaration using <stdatomic.h> and <stdalign.h>. OPT_PROFILE_CACHE_LINE_BYTES is supplied by an approved measured profile. Initialize atomic flags before publication; alignment, fairness and wait policy remain separate obligations.
typedef struct PrivateLockLayout
{
alignas(OPT_PROFILE_CACHE_LINE_BYTES) atomic_flag first_lock;
alignas(OPT_PROFILE_CACHE_LINE_BYTES) atomic_flag second_lock;
} private_lock_layout_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
High-frequency counters and statistics should consider per-CPU, per-thread, or per-shard accumulation with an explicit consolidation operation. The contract must define:
Linux this_cpu operations avoid synchronized cross-CPU cache-line updates and explicitly discourage remote writes to per-CPU data.linux-this-cpu
Contextual example:
Owning-thread fragment. local_count is retained in owner state; ret is local. flush is a validated injected callback; failure must mean no batch committed, otherwise retain explicit partial progress. Flush at deadline and shutdown too; batch size is not the only latency bound.
if (local_count == UINT64_MAX)
{
ret = -ERANGE;
goto function_output;
}
local_count++;
if (local_count >= flush_threshold)
{
ret = flush(owner_context, local_count);
if (ret != EXIT_SUCCESS)
goto function_output;
local_count = 0u;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
A hot shared update may test whether the desired state already exists before performing a write when:
This technique must not replace a required atomic read-modify-write or turn a correct synchronization protocol into a check-then-act race.
Contextual example:
Inside a synchronization owner with exactly one writer. state is an initialized atomic telemetry value, not a publication flag and not a compare-and-swap transaction. observed is declared before validation. Do not apply this form where a repeated release store publishes new payload data.
observed = atomic_load_explicit(state, memory_order_relaxed);
if (observed != requested)
atomic_store_explicit(state, requested, memory_order_relaxed);
Class: PERFORMANCE. Apply the scope and requirement words below.
Code must not remotely modify write-hot per-owner state unless the protocol explicitly synchronizes that access and measurement justifies it. Even a rare remote write can evict the cache line needed when the owning CPU wakes. Linux recommends asking the remote CPU to perform the update when practical.linux-this-cpu
Contextual example:
Cross-owner request. enqueue_update is an injected callback whose success copies or explicitly retains update. It must not retain an automatic DTO borrowed only for the call. No direct write through a remote owner-state pointer.
ret = enqueue_update(queue_context, owner_id, &update);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Do not pack independently modified hot flags, counters, or locks into one word or cache line merely to reduce object size. Bit packing can force unrelated writers through the same read-modify-write location; compact fields can also increase false sharing and make independent atomic updates impossible.
Conversely, do not expand every boolean blindly. When layout matters, use an explicit fixed-width representation and verify the final object and cache-line layout on every target profile. Linux notes that the size and alignment of bool vary with architecture and advises against it where cache-line layout or value size matters.linux-bool-layout
Contextual example:
Profile-specific private layout using <stdatomic.h>/<stdalign.h>. Compare space/TLB cost before adoption; atomic init and matching acquire/release protocol are still required. Do not pack unrelated writers just because each value is a boolean.
typedef struct PrivateOwnerFlags
{
alignas(OPT_PROFILE_CACHE_LINE_BYTES) atomic_bool producer_ready;
alignas(OPT_PROFILE_CACHE_LINE_BYTES) atomic_bool consumer_ready;
} private_owner_flags_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
An object allocated by one CPU, thread, shard, heap, or NUMA node and released by another crosses an ownership boundary even when the allocator API makes the operation legal. A hot design must measure remote-free frequency, atomic traffic, reclamation delay, memory growth, and owner shutdown behavior.
Prefer owner-local reclamation or a bounded deferred-free queue when it improves the measured workload and preserves the lifetime contract. Do not add a global free list as the default remedy. mimalloc separates thread-local and concurrent free lists so the common local path avoids the coordination needed by remote freeing.mimalloc-design
Contextual example:
Cross-owner free port. The ID is a validated non-pointer handle with generation protection. Success transfers release responsibility exactly once; failure retains it with the caller. Queue drain and owner shutdown are part of the contract.
ret = enqueue_remote_free(queue_context, allocation_id);
if (ret != EXIT_SUCCESS)
goto function_output;
allocation_id = INVALID_ALLOCATION_ID;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A hot store followed immediately by an overlapping dependent load should use a size, start address, and containment geometry supported by the target's store-forwarding rules. If PMU events identify forwarding stalls, first reshape the producer store or eliminate the immediate round trip through memory.
Code must still satisfy effective-type, alignment, bounds, and provenance rules; performance evidence never authorizes type-punning through a pointer cast.
Contextual example:
Local representation example: include <stdint.h>/<string.h>; uint32_t word is declared at function entry. bytes is valid disjoint storage for sizeof(word) bytes, replacement is uint8_t, and the intended operation changes the least-significant eight value bits in native representation. Inspect generated code; this is not portable external byte-order decoding and it does not promise a forwarding improvement.
memcpy(&word, bytes, sizeof(word)); word = (word & UINT32_C(0xFFFFFF00)) | (uint32_t)replacement; memcpy(bytes, &word, sizeof(word));
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Independent hot load and store streams may be placed so their low address bits differ when target counters prove false dependency caused by 4 KiB aliasing. Intel documents the condition as a store followed by a load to a different location separated by a 4 KiB offset.intel-optimization
Padding or allocator changes for this purpose must record page size, cache geometry, memory overhead, and the exact affected target.
Contextual example:
Harness callbacks collect real addresses/layout on a declared platform. Pointer ordering or subtraction between unrelated objects is not used. Compare equal/different low page offsets only inside the platform measurement adapter.
/* Read actual layout and PMU events; do not change buffer alignment blindly. */
ret = record_layout(layout_context, source, destination, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = run_variant(benchmark_context, source, destination, size_bytes);
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Hot loops should remove stores that do not change required observable state. Review redundant zeroing, repeated state publication, write-only temporary objects, and read-modify-write sequences whose result is discarded.
The removal must preserve secure-erasure, MMIO, atomic, persistence, and diagnostic contracts. A store required by those contracts is observable even if ordinary C logic never reads it.
Contextual example:
Owner-local accumulation before one output write. sum and index are entry declarations. checked_add is a validated callback with in-place output permitted. No observer may require an intermediate store, and out must not overlap unread samples.
for (index = 0u; index < sample_count; index++)
{
ret = checked_add(sum, samples[index], &sum);
if (ret != EXIT_SUCCESS)
goto function_output;
}
*out = sum;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Hot scalar and vector accesses should not cross the target's expensive cache-line or page boundary when layout control is practical. The implementation must use alignof, alignas, or a project layout abstraction rather than repeat an unexplained numeric alignment.
An atomic or locked operand must never intentionally straddle a cache-line boundary. Target hardware detection for split locks should remain enabled in test and deployment profiles when available.
Contextual example:
Target-profile declaration. The vector alignment comes from the selected backend and allocation contract. Capacity 256 is an illustrative private block size, not a performance claim. Tail handling must remain within the real object extent.
typedef struct PrivateVectorBlock
{
alignas(OPT_PROFILE_VECTOR_ALIGNMENT) unsigned char bytes[256];
} private_vector_block_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A performance-critical thread, its mutable working set, its producer or consumer, device queues, and relevant interrupts should have one documented NUMA-locality plan. CPU affinity must not change independently of memory placement without measuring remote-memory cost.
Linux page migration exists to reduce access latency by moving pages nearer the processor that uses them.linux-page-migration NUMA policy must remain a deployment decision; portable module logic consumes an adapter-owned policy.
Contextual example:
In-process DTO using <stdint.h>. A single runtime/platform owner applies and verifies the plan. The IDs are platform identifiers; equal numeric IDs across the fields do not imply locality.
typedef struct PlacementPlan
{
uint32_t cpu_id;
uint32_t memory_node_id;
uint32_t irq_cpu_id;
uint32_t device_node_id;
} placement_plan_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When PMU evidence shows TLB misses or page walks, evaluate page locality, working-set size, mapping stability, and supported larger page sizes. Do not infer translation locality from a good L1 or LLC hit rate.
Transparent huge pages can map more memory with one TLB entry, but they also change fault, clearing, fragmentation, latency, and memory behavior. Their use requires workload evidence and a fallback policy.linux-thp
Contextual example:
Harness record using <stddef.h>/<stdint.h>. Populate with target-defined PMU events and measured elapsed time. A missing PMU capability is recorded as unavailable, not as a zero result.
typedef struct TranslationEvidence
{
size_t page_size_bytes;
size_t mapped_bytes;
uint64_t page_walk_count;
uint64_t tlb_miss_count;
uint64_t elapsed_ns;
} translation_evidence_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Kernel, runtime, and memory-manager code must target the smallest correct CPU set and virtual-address range when invalidating translations. Hot algorithms should avoid frequent mapping, unmapping, or protection changes when stable mappings provide equivalent isolation.
Linux distinguishes global, address-space, range, and page invalidation and notes that a CPU which never ran an address space need not receive its flush.linux-cachetlb
Contextual example:
Privileged platform-owner fragment with a validated callback. The adapter computes the complete required CPU set and address range and supplies architecture-required barriers. Ordinary module code never omits a required remote invalidation for speed.
ret = invalidate_range(address_space_context, start_page, page_count,
participating_cpu_set);
if (ret != EXIT_SUCCESS)
goto function_output;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When a workload has unexplained conflict misses despite adequate nominal cache capacity, allocator or kernel owners may investigate cache-set placement and page coloring. Application code must not encode undocumented physical-address assumptions.
The experiment must record the physical-index information available to the software, the target cache geometry, page migration behavior, and the memory fragmentation tradeoff.
Contextual example:
An allocator-level experiment record. Physical placement or cache hashing must not be inferred from portable pointer bits. Keep a baseline, working set and byte consumption comparable.
typedef struct PlacementExperiment
{
size_t allocation_stride_bytes;
size_t working_set_bytes;
uint32_t allocator_variant_id;
const char *cache_event_record;
} placement_experiment_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
A latency-critical path that cannot tolerate major faults, first-touch allocation, lazy commitment, or page-table construction must define when its working set is allocated, touched, committed, and released. Pre-faulting or locking memory is permitted only for a bounded set with an explicit resource limit, privilege/failure policy, NUMA placement, and measurement of system-wide impact.
Do not call mlockall, touch arbitrary process memory, or disable paging as a generic speed optimization. DPDK documents memory locking as one option for avoiding page faults in deterministic data-plane execution, while also making NUMA and huge-page placement part of the design.dpdk-performance
Contextual example:
Lifecycle-owner fragment, before the bounded phase starts. The platform callback defines prefault/locking rights, resource limits and failure behavior. This does not claim that a hosted OS becomes hard real time.
ret = prepare_resident_pages(memory_context, buffer, capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = enter_bounded_phase(runtime_context);
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Hot item-by-item processing should consider paying one global atomic operation per validated batch rather than per item. The batch contract must preserve capacity, overflow, failure atomicity, fairness, and bounded latency.
DPDK documents improved performance from bulk operations because a burst can share bookkeeping and expensive atomic work.dpdk-performance
Contextual example:
Owning-thread body. flush_batch must define one commit point and all-or-nothing failure here. Counters/queues define shutdown flush, maximum delay, overflow and fairness separately. A partial-success transport needs a progress field instead of this reset.
ret = flush_batch(owner_context, pending_count);
if (ret != EXIT_SUCCESS)
goto function_output;
pending_count = 0u;
Class: PERFORMANCE. Apply the scope and requirement words below.
Ordinary module logic should call semantic operations such as queue publication, reference acquisition, or snapshot reading. Raw memory orders and fences belong inside a small reviewed synchronization abstraction.
The abstraction must document the weakest sufficient ordering and its matching operation. Stronger ordering must not be emitted merely because the protocol was not analyzed.
Contextual example:
Consumer-owned port declaration. Its owner defines full/closed states, memory ordering, lifetime and bounded execution. The consumer does not invent an atomic protocol at the call site.
typedef int (*queue_try_push_cb_t)(void *context, const unsigned char *data,
size_t size_bytes);
Class: PERFORMANCE. Apply the scope and requirement words below.
RCU, sequence counters, immutable snapshots, and copy-on-write structures are specialized synchronization schemes, not generic replacements for locks.
Selection must document reader/writer ratio, retry bounds, reclamation, pointer lifetime, preemption, real-time behavior, and writer serialization.
Contextual example:
Function-tail fragment. ret and snapshot are declared and initialized at entry. Validated callbacks implement retention/reclamation, and release_snapshot is infallible. A retry counter or read-only access alone does not protect pointed-to objects.
ret = acquire_snapshot(snapshot_context, &snapshot);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = lookup(snapshot_context, snapshot, key, out);
function_output : if (snapshot != (const snapshot_t *)(NULL))
{
release_snapshot(snapshot_context, snapshot);
}
return ret;
Class: PERFORMANCE. Apply the scope and requirement words below.
Lockless shared-memory protocols must not assume that one source-level read or write becomes one machine access unless an approved access primitive establishes that property. Use the project's atomic or single-access wrapper; do not use a raw volatile object as a concurrency primitive.
Linux documents that READ_ONCE() and WRITE_ONCE() prevent transformations such as merged, invented, or torn accesses, while not acting as general CPU memory barriers.linux-memory-barriers
Contextual example:
Synchronization-owner fragment after validating shared_value and its lifetime. Include <stdatomic.h>. The matching publication is specified by the protocol; this ISO C example does not implement Linux READ_ONCE or guarantee a particular single machine instruction.
value = atomic_load_explicit(shared_value, memory_order_acquire);
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A contended synchronization path must define when a waiter spins, yields, parks, or sleeps, and how a releaser chooses wake-one, wake-many, or requeue behavior. The policy must match the expected critical-section duration, CPU count, oversubscription, scheduler class, and latency target.
Do not use an unbounded spin loop as the default fallback. Do not wake every waiter when only one can make progress unless measurement proves that the extra wakeups help the workload. Linux futex documentation describes a fast uncontended user-space path and kernel arbitration for contention; futex requeue operations exist in part to avoid thundering-herd wakeups.linux-futex
Contextual example:
Synchronization-owner fragment. Entry-declared counters/flags; validated callbacks. park_until_change must atomically verify the generation before sleeping to avoid a lost wakeup. Waking does not grant ownership; the caller retries acquisition before touching protected data.
while (!is_ready && (attempt_count < spin_limit))
{
is_ready = try_acquire(lock_context);
attempt_count++;
}
if (!is_ready)
{
ret = park_until_change(lock_context, observed_generation);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Inlining, unrolling, duplicated specialization, error handling, tracing, and instrumentation must be evaluated for instruction-cache and decoded-instruction footprint when the workload is front-end bound. Executed instruction count alone does not describe front-end pressure.
Cold diagnostics and rare fallback paths should remain out of line when profile evidence shows that their placement expands the hot working set.
Contextual example:
Run on the produced executable, together with the representative workload and target front-end events. Byte count alone is not a throughput measurement.
size build-release/tests_static objdump -d build-release/tests_static > tests-static.disassembly.txt
Class: PERFORMANCE. Apply the scope and requirement words below.
static inline may express a small header-local or type-safe wrapper. A forced inline or compiler-specific always-inline attribute requires one of:
Forced inlining must not serve as a generic performance annotation.
Contextual example:
Small module-local helper using <stddef.h>. The infallible accessor return-type exception permits size_t ret but not extra exits. No forced-inline attribute is used; inspect code size and target results before adding one.
static inline size_t opt_minSize(size_t left, size_t right)
{
size_t ret = 0u;
ret = left < right ? left : right;
goto function_output;
function_output:
return ret;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A conditional branch should become a conditional move, mask operation, or other branchless sequence only after evaluating predictability, both operand costs, dependency-chain length, side-channel requirements, and the target cost model.
LLVM's branch-versus-conditional-move work models prediction and critical-path cost separately; neither form wins universally.llvm-cmov
Language-level conditional-operator restrictions in CSTYLE-133 still apply.
Contextual example:
Function-body fragment with validated inputs and entry-declared selected. Compare it with selected = left < right ? left : right under the same contract. Neither C syntax guarantees branch or cmov machine code.
if (left < right)
selected = left;
else
selected = right;
Class: PERFORMANCE. Apply the scope and requirement words below.
likely, unlikely, compiler expectation intrinsics, and branch-weight metadata must reflect a measured deployment profile. CI should diagnose stale hints when tooling supports it. LLVM's MisExpect diagnostics compare expected and observed profile weights.llvm-misexpect
Contextual example:
OPT_UNLIKELY__ is a project compiler-adapter macro with a plain-expression fallback and single evaluation. Use only for a measured stable rare path; the probability is not guessed from the name. ret was assigned outside the condition.
if (OPT_UNLIKELY__(ret != EXIT_SUCCESS))
goto function_output;
Class: PERFORMANCE. Apply the scope and requirement words below.
Runtime code patching or static-key mechanisms may remove a repeated hot-path test when the default state is overwhelmingly stable and updates are rare. The patching abstraction must own instruction atomicity, synchronization, architecture support, writable-code policy, cache maintenance, and fallback.
Linux static keys replace the recurring path with architecture-supported jump label patching and fall back to a normal load/test/branch sequence when support is absent.linux-static-keys
Contextual example:
feature_is_enabled is an infallible read-only predicate from a bound port. A platform implementation may use a static key only under its approved patching, lifetime and I-cache synchronization contract. The ordinary module performs no text patching.
if (feature_is_enabled(feature_context))
{
ret = trace(trace_context, event);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When a function target cannot change during a hot loop, the dispatch owner may bind it once outside the loop. The binding must preserve lifetime, callback validation, synchronization, instrumentation, and hot-update behavior.
This technique is profile-gated; it must not cache a callback across a point that can mutate or invalidate the callback table.
Contextual example:
Declare process, process_context, index and ret at entry, with typed NULL for pointers. Validate the table, mandatory callback and item extent before this fragment. The binder prevents replacement/unload for the entire loop. This is not permission to bypass callback instrumentation.
process = callbacks->process;
process_context = callbacks->process_context;
for (index = 0u; index < item_count; index++)
{
ret = process(process_context, &items[index]);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Manual function, loop, or basic-block alignment must not be applied globally. Use PGO, linker layout, or target-specific placement only after front-end events identify a placement problem. Record code-size growth and effects on other hot regions.
Deep tiny-call chains or recursion in a front-end-bound path may be investigated for return-prediction pressure, but no fixed call-depth limit can be inferred from one CPU generation.
Contextual example:
Commands on a built ELF test binary. A target owner may compare PGO/layout variants, but no arbitrary alignment threshold is asserted here.
# Inspect the final text layout for the actual optimized build. readelf -S build-release/tests_static objdump -d build-release/tests_static > final-layout.txt
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Software prefetch requires:
Do not add software prefetch to a workload already limited by memory bandwidth. Pipeline several independent objects when that provides useful work between prefetch and consumption.
Contextual example:
Entry-declared index/distance/ret; validated callbacks and full array extent. prefetch is infallible and must not retain the pointer. distance is selected by a measured profile; subtraction is safe because index < item_count. Measure pollution and bandwidth, not just demand misses.
for (index = 0u; index < item_count; index++)
{
if (distance < item_count - index)
prefetch(prefetch_context, &items[index + distance]);
ret = consume(consume_context, &items[index]);
if (ret != EXIT_SUCCESS)
goto function_output;
}
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
DMA descriptors, producer/consumer flags, and payload placement must follow the platform coherency contract. Where the device and memory subsystem benefit from it, burst structures should permit complete cache-line DMA writes instead of repeated partial-line writes. DPDK documents lower cost for full cache-line PCI DMA writes.dpdk-performance
Padding must not place independently written CPU and DMA ownership fields in the same coherence unit.
Contextual example:
A platform-owner descriptor, not a wire format. Include <stddef.h>/<stdint.h>. The mapping contract defines actual alignment, coherency, cache maintenance, permitted cache-line rounding and ownership handover. used_bytes never authorizes stores into adjacent allocations.
typedef struct DmaBufferView
{
unsigned char *data;
size_t capacity_bytes;
size_t used_bytes;
uint32_t mapping_id;
} dma_buffer_view_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
Non-temporal or write-combining stores may be used only when measurement shows a large write stream with little near-term CPU reuse and harmful cache pollution. They must not become the default implementation of a large copy.
The adapter contract must define alignment, minimum profitable size, fallback, ordering, completion, and publication. Before another CPU or device receives a ready flag, the implementation must issue the architecture-defined ordering or completion operation for preceding streaming stores.
Contextual example:
Platform-owner sequence through validated callbacks. complete_stores supplies target/device completion and ordering, not merely a compiler barrier. Do not publish on either preceding failure. The backend defines aliasing, alignment, profitable-size threshold and cached fallback.
ret = stream_copy(stream_context, destination, source, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = complete_stores(stream_context);
if (ret != EXIT_SUCCESS)
goto function_output;
ret = publish_ready(publication_context);
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
When a measured write-combining path permits it, complete one cache line before interleaving partial writes to many lines. The implementation must use the platform cache-line abstraction and must retain a correct tail path for partial final data.
This rule does not authorize writing bytes outside the destination capacity.
Contextual example:
Entry declarations and validation precede this body; line_bytes is nonzero and cursor names the remaining span. Callbacks must not overrun it. Tail code must not round the logical length up into unowned bytes. Publication follows the platform completion protocol.
while (remaining_bytes >= line_bytes)
{
ret = write_line(stream_context, cursor, line_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
cursor += line_bytes;
remaining_bytes -= line_bytes;
}
if (remaining_bytes != 0u)
ret = write_tail(stream_context, cursor, remaining_bytes);
Class: PERFORMANCE. Apply the scope and requirement words below.
Related pitfalls:
A memory-latency experiment must account for the target hardware prefetchers. Regular streams may already benefit from stride or adjacent-line behavior; extra software prefetch can duplicate work, consume miss-handling resources, or pollute caches. Intel recommends favoring automatic hardware prefetch for long, regular patterns and warns that excessive software prefetch consumes machine and bus resources.intel-optimization
If the platform exposes a supported way to change prefetcher policy, compare the same workload under the relevant states before attributing a gain to layout or software prefetch. Record the effective policy with the benchmark baseline.
Contextual example:
An actual A/B measurement record supplied by the target owner. Never change system-wide prefetch policy from ordinary library code or claim unsupported PMU counters are zero.
typedef struct PrefetchExperiment
{
const char *effective_hardware_policy;
size_t software_distance_items;
const char *cache_events;
const char *translation_events;
const char *bandwidth_events;
} prefetch_experiment_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
Every accepted microarchitectural optimization must retain a review record with:
Contextual example:
Evidence paths must resolve to actual run artifacts. This type is not a completed approval record.
typedef struct OptimizationReview
{
const char *rule_ids;
const char *baseline_record;
const char *candidate_record;
const char *correctness_log;
const char *regression_policy;
const char *rollback_trigger;
const char *owner;
} optimization_review_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
CI for each specialized backend must:
Contextual example:
Harness fragment with entry-declared IDs and ret. selected_backend reports the implementation that will execute; unsupported hardware is not silently counted as passing the optimized test.
ret = selected_backend(dispatch_context, &actual_backend_id);
if (ret != EXIT_SUCCESS)
goto function_output;
if (actual_backend_id != requested_backend_id)
{
ret = -ENOTSUP;
goto function_output;
}
ret = differential_test(test_context);
Class: PERFORMANCE. Apply the scope and requirement words below.
Automated performance gates must define noise handling, sample count, confidence or robust summary, machine isolation, retry policy, and escalation threshold. One noisy run must not rewrite a target-wide rule.
Contextual example:
Populate from an approved benchmark policy; no arbitrary threshold or claimed speedup is supplied. Include <stddef.h>/<stdint.h>. Record variability and bytes/latency as well as throughput.
typedef struct RegressionPolicy
{
size_t warmup_count;
size_t sample_count;
uint32_t allowed_regression_ppm;
uint32_t maximum_retries;
const char *summary_method;
} regression_policy_t;
Class: PERFORMANCE. Apply the scope and requirement words below.
A checker, compiler remark, profiler, or cost model reports evidence. It does not redefine the governing control. A documented human review may reject a heuristic diagnostic, but it must preserve the measurement and rationale for later audit.
Contextual example:
A diagnostic is resolved by fixing the code or by a scoped approved deviation. An empty deviation field does not itself grant permission.
typedef struct DiagnosticDisposition
{
const char *rule_id;
const char *tool_version;
const char *diagnostic_id;
const char *evidence_path;
const char *approved_deviation_id;
} diagnostic_disposition_t;
These restrictions apply to the named platform/API when present. Absence of an API from this table is not approval. Review actions require evidence of bounds, ownership, error checking, execution context, and the replacement's semantics. The API family name does not prove a wrapper safe. A proposed review exception must name the corresponding CSTYLE control and the selected execution profile.
Restrictions on ctype/strlen uses depend on their invalid preconditions, not solely on whether data originated outside the module. Untrusted executable loading without validation is a banned pattern. A secure erase or comparison requires a qualified primitive, not just a generic optimization barrier.
The following files are complete source files, not independent fragments. They compile together with the emitter, compiler adapter, composition, and CMake files in the architectureexample. The test program checks the same interfaces.
The buffer owns a control object and its byte allocation. A caller-supplied allocator family supplies and releases both; its context is borrowed. All operations require external synchronization. Resize is transactional on failure, zero size frees payload storage without calling realloc, and growth exposes only initialized bytes. Append requires an independent borrowed input span. The API does not export an internal data pointer. Copy states its capacity and output count behavior explicitly. The payload budget excludes the control object's fixed overhead, which a system-wide memory budget must also account for.
CHECKED_* is an approved stateless foundation, not a peer. Its helpers perform bounds checks before arithmetic and keep outputs unchanged on failure. The four-octet codec demonstrates a specified wire representation independently of C struct layout. The decimal parser has an explicit ten-digit work limit.
/*
* SPDX-FileCopyrightText: 2026 Rafael V. Volkmer
* SPDX-License-Identifier: GPL-3.0-only
*/
#if !defined(SAMPLE_PROJECT_STATUS_H)
#define SAMPLE_PROJECT_STATUS_H
/* Project values, not POSIX errno numbers. Zero means success. */
enum ProjectStatus
{
PROJECT_OK = 0,
PROJECT_ERR_INVALID = -1,
PROJECT_ERR_RANGE = -2,
PROJECT_ERR_MEMORY = -3,
PROJECT_ERR_CAPACITY = -4,
PROJECT_ERR_BUSY = -5,
PROJECT_ERR_IO = -6
};
#endif
/*
* SPDX-FileCopyrightText: 2026 Rafael V. Volkmer
* SPDX-License-Identifier: GPL-3.0-only
*/
#if !defined(SAMPLE_MEMORY_PORT_H)
#define SAMPLE_MEMORY_PORT_H
#include <stddef.h>
/*
* alloc: positive size; suitable alignment for fundamental object types.
* resize: non-NULL owned base and positive size. NULL preserves the old
* allocation. Success invalidates the old pointer and all its aliases.
* release: accepts NULL; otherwise requires this family's owned base.
* Calls may allocate or block; not ISR/signal-safe in this host profile.
* None of these callbacks re-enters the consuming module or fails nonlocally.
* The binder keeps context and callback code alive through module destruction.
* The table is copied; context is borrowed. These are in-process contracts.
*/
typedef void *(*memory_alloc_fn_t)(void *context, size_t size_bytes);
typedef void *(*memory_resize_fn_t)(void *context, void *base,
size_t size_bytes);
typedef void (*memory_release_fn_t)(void *context, void *base);
typedef struct MemoryPort
{
void *context;
memory_alloc_fn_t alloc;
memory_resize_fn_t resize;
memory_release_fn_t release;
} memory_port_t;
#endif
/* * SPDX-FileCopyrightText: 2026 Rafael V. Volkmer * SPDX-License-Identifier: GPL-3.0-only */ #if !defined(SAMPLE_CHECKED_H) #define SAMPLE_CHECKED_H #include <stddef.h> #include <stdint.h> /* * Thread-safe for disjoint outputs. No allocation or retained pointers. * out must name a writable object of its declared type. On error it is * unchanged. NULL is rejected. Input/output objects must not overlap. */ int CHECKED_addSize(size_t left, size_t right, size_t *out); int CHECKED_mulSize(size_t left, size_t right, size_t *out); /* Accept 1..10 ASCII decimal digits, no sign, space, NUL, or suffix. */ int CHECKED_parseU32(const char *text, size_t length, uint32_t *out); /* Four-octet big-endian representation. Require CHAR_BIT == 8. */ int CHECKED_encodeU32(uint32_t value, uint8_t *out, size_t capacity); int CHECKED_decodeU32(const uint8_t *data, size_t length, uint32_t *out); #endif
/*
* SPDX-FileCopyrightText: 2026 Rafael V. Volkmer
* SPDX-License-Identifier: GPL-3.0-only
*/
#include "checked.h"
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include "project_status.h"
#define CHECKED_U32_OCTETS ((size_t)4u)
#define CHECKED_BITS_PER_OCTET ((size_t)8u)
#define CHECKED_DECIMAL_DIGITS_MAX ((size_t)10u)
#define CHECKED_DECIMAL_BASE UINT32_C(10)
#define CHECKED_OCTET_MASK UINT32_C(255)
#define CHECKED_ASCII_ZERO 0x30
#define CHECKED_ASCII_NINE 0x39
_Static_assert(CHAR_BIT == CHECKED_BITS_PER_OCTET,
"The sample wire format uses octets");
_Static_assert('0' == CHECKED_ASCII_ZERO, "ASCII zero required");
_Static_assert('9' == CHECKED_ASCII_NINE, "ASCII nine required");
int CHECKED_addSize(size_t left, size_t right, size_t *out)
{
int ret = PROJECT_OK;
if (out == (size_t *)(NULL))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if (left > SIZE_MAX - right)
{
ret = PROJECT_ERR_RANGE;
goto function_output;
}
*out = left + right;
function_output:
return ret;
}
int CHECKED_mulSize(size_t left, size_t right, size_t *out)
{
int ret = PROJECT_OK;
if (out == (size_t *)(NULL))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if ((right != 0u) && (left > SIZE_MAX / right))
{
ret = PROJECT_ERR_RANGE;
goto function_output;
}
*out = left * right;
function_output:
return ret;
}
int CHECKED_parseU32(const char *text, size_t length, uint32_t *out)
{
int ret = PROJECT_OK;
unsigned char ch = 0u;
size_t index = 0u;
uint32_t value = 0u;
uint32_t digit = 0u;
if ((text == (const char *)(NULL)) || (out == (uint32_t *)(NULL)))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if ((length == 0u) || (length > CHECKED_DECIMAL_DIGITS_MAX))
{
ret = PROJECT_ERR_RANGE;
goto function_output;
}
for (index = 0u; index < length; index++)
{
ch = (unsigned char)text[index];
if ((ch < (unsigned char)'0') || (ch > (unsigned char)'9'))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
digit = (uint32_t)(ch - (unsigned char)'0');
if (value > (UINT32_MAX - digit) / CHECKED_DECIMAL_BASE)
{
ret = PROJECT_ERR_RANGE;
goto function_output;
}
value = (value * CHECKED_DECIMAL_BASE) + digit;
}
*out = value;
function_output:
return ret;
}
int CHECKED_encodeU32(uint32_t value, uint8_t *out, size_t capacity)
{
int ret = PROJECT_OK;
size_t index = 0u;
unsigned int shift = 0u;
if (out == (uint8_t *)(NULL))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if (capacity < CHECKED_U32_OCTETS)
{
ret = PROJECT_ERR_CAPACITY;
goto function_output;
}
for (index = 0u; index < CHECKED_U32_OCTETS; index++)
{
shift = (unsigned int)((CHECKED_U32_OCTETS - 1u - index) *
CHECKED_BITS_PER_OCTET);
out[index] = (uint8_t)((value >> shift) & CHECKED_OCTET_MASK);
}
function_output:
return ret;
}
int CHECKED_decodeU32(const uint8_t *data, size_t length, uint32_t *out)
{
int ret = PROJECT_OK;
size_t index = 0u;
uint32_t value = 0u;
if ((data == (const uint8_t *)(NULL)) || (out == (uint32_t *)(NULL)))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if (length != CHECKED_U32_OCTETS)
{
ret = PROJECT_ERR_RANGE;
goto function_output;
}
for (index = 0u; index < CHECKED_U32_OCTETS; index++)
{
value = (value << CHECKED_BITS_PER_OCTET) |
(uint32_t)data[index];
}
*out = value;
function_output:
return ret;
}
/*
* SPDX-FileCopyrightText: 2026 Rafael V. Volkmer
* SPDX-License-Identifier: GPL-3.0-only
*/
#if !defined(SAMPLE_BUFFER_H)
#define SAMPLE_BUFFER_H
#include <stddef.h>
#include <stdint.h>
#include "compiler_api.h"
#include "memory_port.h"
/*
* Opaque, non-copyable. All operations require external synchronization.
* The host profile provides no ISR/signal-safety or real-time guarantee.
* Debug invariant failure follows the sample profile's abort policy.
*/
typedef struct Buffer buffer_t;
/*
* out points to an initialized NULL handle; unchanged on failure.
* memory is copied. Its borrowed context/code outlives the buffer.
* max_size_bytes > 0 is a payload budget; the control object is additional.
* create allocates only the control object, using the supplied family.
*/
BUFFER_API int BUFFER_create(buffer_t **out, const memory_port_t *memory,
size_t max_size_bytes);
/*
* May allocate. Failure leaves size and contents unchanged.
* Growth zeroes newly exposed bytes. Zero releases payload storage without
* invoking resize with zero. All internal aliases expire after success.
*/
BUFFER_API int BUFFER_resize(buffer_t *buffer, size_t size_bytes);
/*
* May allocate. data is borrowed for this call and readable for size_bytes.
* NULL data is allowed only for zero bytes. data must not refer to the buffer
* control object or its storage. Failure leaves contents/size unchanged.
*/
BUFFER_API int BUFFER_append(buffer_t *buffer, const uint8_t *data,
size_t size_bytes);
/*
* No allocation. written is required and receives zero on failure.
* out may be NULL only with capacity zero. Success copies the whole payload.
* All writable outputs must be disjoint from each other and buffer storage.
* A non-NULL out must name at least capacity writable bytes.
*/
BUFFER_API int BUFFER_copy(const buffer_t *buffer, uint8_t *out,
size_t capacity, size_t *written);
/* handle is required; *handle may be NULL. Success releases and clears it. */
BUFFER_API int BUFFER_destroy(buffer_t **handle);
#endif
/*
* SPDX-FileCopyrightText: 2026 Rafael V. Volkmer
* SPDX-License-Identifier: GPL-3.0-only
*/
#include "buffer.h"
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "checked.h"
#include "memory_port.h"
#include "project_status.h"
struct Buffer
{
memory_port_t memory;
uint8_t *data;
size_t size_bytes;
size_t max_size_bytes;
};
int BUFFER_create(buffer_t **out, const memory_port_t *memory,
size_t max_size_bytes)
{
int ret = PROJECT_OK;
buffer_t *buffer = (buffer_t *)(NULL);
if ((out == (buffer_t **)(NULL)) ||
(memory == (const memory_port_t *)(NULL)) || (max_size_bytes == 0u))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if ((*out != (buffer_t *)(NULL)) ||
(memory->alloc == (memory_alloc_fn_t)(NULL)) ||
(memory->resize == (memory_resize_fn_t)(NULL)) ||
(memory->release == (memory_release_fn_t)(NULL)))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
buffer = (buffer_t *)memory->alloc(memory->context, sizeof(*buffer));
if (buffer == (buffer_t *)(NULL))
{
ret = PROJECT_ERR_MEMORY;
goto function_output;
}
*buffer = (buffer_t){ .memory = *memory,
.data = (uint8_t *)(NULL),
.size_bytes = 0u,
.max_size_bytes = max_size_bytes };
*out = buffer;
function_output:
return ret;
}
int BUFFER_resize(buffer_t *buffer, size_t size_bytes)
{
int ret = PROJECT_OK;
uint8_t *replacement = (uint8_t *)(NULL);
if (buffer == (buffer_t *)(NULL))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if (size_bytes > buffer->max_size_bytes)
{
ret = PROJECT_ERR_CAPACITY;
goto function_output;
}
if (size_bytes == buffer->size_bytes)
goto function_output;
if (size_bytes == 0u)
{
buffer->memory.release(buffer->memory.context, buffer->data);
buffer->data = (uint8_t *)(NULL);
buffer->size_bytes = 0u;
goto function_output;
}
if (buffer->data == (uint8_t *)(NULL))
{
replacement =
(uint8_t *)buffer->memory.alloc(buffer->memory.context,
size_bytes);
}
else
{
replacement =
(uint8_t *)buffer->memory.resize(buffer->memory.context,
buffer->data,
size_bytes);
}
if (replacement == (uint8_t *)(NULL))
{
ret = PROJECT_ERR_MEMORY;
goto function_output;
}
if (size_bytes > buffer->size_bytes)
{
/* CSTYLE-066: return value repeats the validated destination.
*/
// NOLINTNEXTLINE(bugprone-unused-return-value)
memset(replacement + buffer->size_bytes, 0,
size_bytes - buffer->size_bytes);
}
buffer->data = replacement;
buffer->size_bytes = size_bytes;
function_output:
return ret;
}
int BUFFER_append(buffer_t *buffer, const uint8_t *data, size_t size_bytes)
{
int ret = PROJECT_OK;
size_t old_size = 0u;
size_t new_size = 0u;
if ((buffer == (buffer_t *)(NULL)) ||
((data == (const uint8_t *)(NULL)) && (size_bytes != 0u)))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if (size_bytes == 0u)
goto function_output;
old_size = buffer->size_bytes;
ret = CHECKED_addSize(old_size, size_bytes, &new_size);
if (ret != PROJECT_OK)
goto function_output;
/* Checked addition with a positive addend strictly increases the size.
*/
if (new_size <= old_size)
{
ret = PROJECT_ERR_RANGE;
goto function_output;
}
ret = BUFFER_resize(buffer, new_size);
if (ret != PROJECT_OK)
goto function_output;
/* Input is independent of owned storage by the public contract. */
/* CSTYLE-066: return value repeats the validated destination. */
// NOLINTNEXTLINE(bugprone-unused-return-value)
memcpy(buffer->data + old_size, data, size_bytes);
function_output:
return ret;
}
int BUFFER_copy(const buffer_t *buffer, uint8_t *out, size_t capacity,
size_t *written)
{
int ret = PROJECT_OK;
if (written == (size_t *)(NULL))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
*written = 0u;
if ((buffer == (const buffer_t *)(NULL)) ||
((out == (uint8_t *)(NULL)) && (capacity != 0u)))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if (capacity < buffer->size_bytes)
{
ret = PROJECT_ERR_CAPACITY;
goto function_output;
}
if (buffer->size_bytes != 0u)
{
/* CSTYLE-066: return value repeats the validated destination.
*/
// NOLINTNEXTLINE(bugprone-unused-return-value)
memcpy(out, buffer->data, buffer->size_bytes);
}
*written = buffer->size_bytes;
function_output:
return ret;
}
int BUFFER_destroy(buffer_t **handle)
{
int ret = PROJECT_OK;
memory_port_t memory = { 0 };
buffer_t *buffer = (buffer_t *)(NULL);
if (handle == (buffer_t **)(NULL))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
if (*handle == (buffer_t *)(NULL))
goto function_output;
buffer = *handle;
memory = buffer->memory;
memory.release(memory.context, buffer->data);
memory.release(memory.context, buffer);
*handle = (buffer_t *)(NULL);
function_output:
return ret;
}
The portable reference is compared with a four-byte chunked candidate. Both implementations use byte accesses and reject the same invalid pointers. The test varies offset, length and search byte, including empty inputs and chunk tails. This is a correctness example; it does not claim that chunking is faster. No SIMD, hardware prefetch, NUMA or special store instructions are executed.
#if !defined(SAMPLE_OPTIMIZATION_EXAMPLES_H)
#define SAMPLE_OPTIMIZATION_EXAMPLES_H
#include <stddef.h>
/* Inputs are borrowed; count_out is disjoint writable storage.
* Zero length still requires a non-NULL data pointer. On failure,
* count_out is unchanged. No allocation or ownership transfer occurs.
*/
int OPT_countByteReference(const unsigned char *data, size_t size_bytes,
unsigned char needle, size_t *count_out);
int OPT_countByteChunked(const unsigned char *data, size_t size_bytes,
unsigned char needle, size_t *count_out);
#endif
#include "optimization_examples.h"
#include <stddef.h>
#include <stdlib.h>
#include "project_status.h"
#define OPT_CHUNK_BYTES ((size_t)4u)
#define OPT_THIRD_BYTE ((size_t)2u)
#define OPT_FOURTH_BYTE ((size_t)3u)
/* CSTYLE-057: counted-buffer API; length and search byte have distinct roles.
*/
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
int OPT_countByteReference(const unsigned char *data, size_t size_bytes,
unsigned char needle, size_t *count_out)
{
int ret = EXIT_SUCCESS;
size_t count = 0u;
size_t index = 0u;
if ((data == (const unsigned char *)(NULL)) ||
(count_out == (size_t *)(NULL)))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
for (index = 0u; index < size_bytes; index++)
{
if (data[index] == needle)
count++;
}
*count_out = count;
function_output:
return ret;
}
/* This candidate exercises a four-byte chunk and a scalar tail.
* It makes no target-specific speed claim and uses no wide loads.
*/
/* CSTYLE-057: counted-buffer API; length and search byte have distinct roles.
*/
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
int OPT_countByteChunked(const unsigned char *data, size_t size_bytes,
unsigned char needle, size_t *count_out)
{
int ret = EXIT_SUCCESS;
size_t count = 0u;
size_t index = 0u;
if ((data == (const unsigned char *)(NULL)) ||
(count_out == (size_t *)(NULL)))
{
ret = PROJECT_ERR_INVALID;
goto function_output;
}
while ((size_bytes - index) >= OPT_CHUNK_BYTES)
{
count += (size_t)(data[index] == needle);
count += (size_t)(data[index + 1u] == needle);
count += (size_t)(data[index + OPT_THIRD_BYTE] == needle);
count += (size_t)(data[index + OPT_FOURTH_BYTE] == needle);
index += OPT_CHUNK_BYTES;
}
for (; index < size_bytes; index++)
{
if (data[index] == needle)
count++;
}
*count_out = count;
function_output:
return ret;
}
The table remains the canonical ban/review decision. These local C excerpts show the required boundary or precondition for each entry, including platform aliases. Calls with lower-case names are injected and validated ports in the enclosing operation. Their implementation contracts must be supplied by the owner; these fragments are not claimed to be standalone wrappers or tested native API adapters. All locals belong at function entry, with ret first and the required initial values. The final output label and cleanup are supplied by that enclosing function. Do not change a review action into a ban, or a ban into permission, based only on an illustrative wrapper name.
Action: ban. Canonical entry.
bounded line-input wrapper with explicit capacity and status
Injected bounded-input port: capacity_chars includes any required terminator. Its contract distinguishes EOF, truncation and I/O failure, uses the selected character/encoding domain, and never writes past capacity. Declarations and required callback validation precede this body fragment.
ret = read_line(input_context, buffer, capacity_chars, &length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
bounded text-input wrapper with explicit capacity
Injected bounded-input port: capacity_chars includes any required terminator. Its contract distinguishes EOF, truncation and I/O failure, uses the selected character/encoding domain, and never writes past capacity. Declarations and required callback validation precede this body fragment.
ret = read_line(input_context, buffer, capacity_chars, &length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
project copy wrapper with destination capacity and status
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
wide-string copy wrapper with destination capacity and status
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
platform text wrapper with destination capacity and status
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
encoding-aware bounded copy wrapper
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
platform bounded-copy wrapper
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
platform bounded-copy wrapper
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project copy wrapper with explicit truncation status
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
wide-string wrapper with explicit truncation status
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
platform wrapper with explicit status
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
encoding-aware wrapper with explicit status
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
project append wrapper with remaining capacity and status
Injected append port receives total capacity and current valid length, validates addition and termination space, and documents output state on failure. Use the correct character/encoding unit for the platform API.
ret = append_text(append_context, destination, destination_capacity_chars,
&used_chars, source, source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
wide-string append wrapper with remaining capacity
Injected append port receives total capacity and current valid length, validates addition and termination space, and documents output state on failure. Use the correct character/encoding unit for the platform API.
ret = append_text(append_context, destination, destination_capacity_chars,
&used_chars, source, source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
platform append wrapper with remaining capacity
Injected append port receives total capacity and current valid length, validates addition and termination space, and documents output state on failure. Use the correct character/encoding unit for the platform API.
ret = append_text(append_context, destination, destination_capacity_chars,
&used_chars, source, source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
encoding-aware bounded append wrapper
Injected append port receives total capacity and current valid length, validates addition and termination space, and documents output state on failure. Use the correct character/encoding unit for the platform API.
ret = append_text(append_context, destination, destination_capacity_chars,
&used_chars, source, source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
platform bounded-append wrapper
Injected append port receives total capacity and current valid length, validates addition and termination space, and documents output state on failure. Use the correct character/encoding unit for the platform API.
ret = append_text(append_context, destination, destination_capacity_chars,
&used_chars, source, source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
platform bounded-append wrapper
Injected append port receives total capacity and current valid length, validates addition and termination space, and documents output state on failure. Use the correct character/encoding unit for the platform API.
ret = append_text(append_context, destination, destination_capacity_chars,
&used_chars, source, source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project append wrapper taking total destination capacity
Injected append port receives total capacity and current valid length, validates addition and termination space, and documents output state on failure. Use the correct character/encoding unit for the platform API.
ret = append_text(append_context, destination, destination_capacity_chars,
&used_chars, source, source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
wide append wrapper taking total destination capacity
Injected append port receives total capacity and current valid length, validates addition and termination space, and documents output state on failure. Use the correct character/encoding unit for the platform API.
ret = append_text(append_context, destination, destination_capacity_chars,
&used_chars, source, source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
project formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
project variadic formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
Do not confuse the legacy signature with ISO C swprintf, which has a size parameter.
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
platform formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
platform variadic formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
project formatter requiring result validation
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
project variadic formatter requiring result validation
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
literal format through project logging wrapper
Counted-text logging port: message is data, never a format string. The adapter uses a literal format or a byte-output API, excludes n, and applies redaction and record-injection policy. A failed log must not replace the original operation failure.
ret = log_text(log_context, message, message_length_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
literal format through project logging wrapper
Counted-text logging port: message is data, never a format string. The adapter uses a literal format or a byte-output API, excludes n, and applies redaction and record-injection policy. A failed log must not replace the original operation failure.
ret = log_text(log_context, message, message_length_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
literal format through project logging wrapper
Counted-text logging port: message is data, never a format string. The adapter uses a literal format or a byte-output API, excludes n, and applies redaction and record-injection policy. A failed log must not replace the original operation failure.
ret = log_text(log_context, message, message_length_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
literal format through project logging wrapper
Counted-text logging port: message is data, never a format string. The adapter uses a literal format or a byte-output API, excludes n, and applies redaction and record-injection policy. A failed log must not replace the original operation failure.
ret = log_text(log_context, message, message_length_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
literal format through project logging wrapper
Counted-text logging port: message is data, never a format string. The adapter uses a literal format or a byte-output API, excludes n, and applies redaction and record-injection policy. A failed log must not replace the original operation failure.
ret = log_text(log_context, message, message_length_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
do not use write-through formatting directives
Counted-text logging port: message is data, never a format string. The adapter uses a literal format or a byte-output API, excludes n, and applies redaction and record-injection policy. A failed log must not replace the original operation failure.
ret = log_text(log_context, message, message_length_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
line-input wrapper plus checked conversion parser
Injected bounded-input port: capacity_chars includes any required terminator. Its contract distinguishes EOF, truncation and I/O failure, uses the selected character/encoding domain, and never writes past capacity. Declarations and required callback validation precede this body fragment.
ret = read_line(input_context, buffer, capacity_chars, &length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
line-input wrapper plus checked conversion parser
Injected bounded-input port: capacity_chars includes any required terminator. Its contract distinguishes EOF, truncation and I/O failure, uses the selected character/encoding domain, and never writes past capacity. Declarations and required callback validation precede this body fragment.
ret = read_line(input_context, buffer, capacity_chars, &length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
line-input wrapper plus checked conversion parser
Injected bounded-input port: capacity_chars includes any required terminator. Its contract distinguishes EOF, truncation and I/O failure, uses the selected character/encoding domain, and never writes past capacity. Declarations and required callback validation precede this body fragment.
ret = read_line(input_context, buffer, capacity_chars, &length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
line-input wrapper plus checked conversion parser
Injected bounded-input port: capacity_chars includes any required terminator. Its contract distinguishes EOF, truncation and I/O failure, uses the selected character/encoding domain, and never writes past capacity. Declarations and required callback validation precede this body fragment.
ret = read_line(input_context, buffer, capacity_chars, &length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
checked parser with explicit ranges
Checked parser port: validate the requested numeric domain and upper/lower bounds. Floating parsing additionally specifies NaN, infinity, locale and range behavior. The destination type follows the port contract; consumption alone does not prove range validity.
ret = parse_number(parser_context, text, text_length_bytes, &parsed_value,
&consumed_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
if (consumed_bytes != text_length_bytes)
{
ret = -EINVAL;
goto function_output;
}
Action: review. Canonical entry.
checked parser with explicit ranges
Checked parser port: validate the requested numeric domain and upper/lower bounds. Floating parsing additionally specifies NaN, infinity, locale and range behavior. The destination type follows the port contract; consumption alone does not prove range validity.
ret = parse_number(parser_context, text, text_length_bytes, &parsed_value,
&consumed_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
if (consumed_bytes != text_length_bytes)
{
ret = -EINVAL;
goto function_output;
}
Action: ban. Canonical entry.
checked integer parser with end-pointer, range, and domain validation
Checked parser port: validate the requested numeric domain and upper/lower bounds. Floating parsing additionally specifies NaN, infinity, locale and range behavior. The destination type follows the port contract; consumption alone does not prove range validity.
ret = parse_number(parser_context, text, text_length_bytes, &parsed_value,
&consumed_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
if (consumed_bytes != text_length_bytes)
{
ret = -EINVAL;
goto function_output;
}
Action: ban. Canonical entry.
checked integer parser with end-pointer, range, and domain validation
Checked parser port: validate the requested numeric domain and upper/lower bounds. Floating parsing additionally specifies NaN, infinity, locale and range behavior. The destination type follows the port contract; consumption alone does not prove range validity.
ret = parse_number(parser_context, text, text_length_bytes, &parsed_value,
&consumed_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
if (consumed_bytes != text_length_bytes)
{
ret = -EINVAL;
goto function_output;
}
Action: ban. Canonical entry.
checked integer parser with end-pointer, range, and domain validation
Checked parser port: validate the requested numeric domain and upper/lower bounds. Floating parsing additionally specifies NaN, infinity, locale and range behavior. The destination type follows the port contract; consumption alone does not prove range validity.
ret = parse_number(parser_context, text, text_length_bytes, &parsed_value,
&consumed_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
if (consumed_bytes != text_length_bytes)
{
ret = -EINVAL;
goto function_output;
}
Action: ban. Canonical entry.
checked floating parser with end-pointer, range, and domain validation
Checked parser port: validate the requested numeric domain and upper/lower bounds. Floating parsing additionally specifies NaN, infinity, locale and range behavior. The destination type follows the port contract; consumption alone does not prove range validity.
ret = parse_number(parser_context, text, text_length_bytes, &parsed_value,
&consumed_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
if (consumed_bytes != text_length_bytes)
{
ret = -EINVAL;
goto function_output;
}
Action: review. Canonical entry.
project formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project formatter with explicit capacity and checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
explicit parser state wrapper
Parser-owned explicit state; input_end and cursor belong to the same validated array. Specify empty-token handling, mutation and token lifetime. No hidden shared strtok cursor is permitted.
ret = next_token(parser_context, &cursor, input_end, &token_begin,
&token_size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
explicit parser wrapper with documented ownership
Parser-owned explicit state; input_end and cursor belong to the same validated array. Specify empty-token handling, mutation and token lifetime. No hidden shared strtok cursor is permitted.
ret = next_token(parser_context, &cursor, input_end, &token_begin,
&token_size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
explicit parser wrapper with documented semantics
Parser-owned explicit state; input_end and cursor belong to the same validated array. Specify empty-token handling, mutation and token lifetime. No hidden shared strtok cursor is permitted.
ret = next_token(parser_context, &cursor, input_end, &token_begin,
&token_size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
Use tracked length or establish a terminator within the readable extent before scanning.
The port searches only the known readable extent and fails when no terminator exists. Use byte or wide-character units as appropriate; a capacity argument does not by itself prove the pointer has that extent.
ret = bounded_length(text_context, text, readable_capacity_chars,
&length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
Use tracked length or establish a terminator within the readable extent before scanning.
The port searches only the known readable extent and fails when no terminator exists. Use byte or wide-character units as appropriate; a capacity argument does not by itself prove the pointer has that extent.
ret = bounded_length(text_context, text, readable_capacity_chars,
&length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
Use memmove for intentionally overlapping validated byte ranges, or prove that the ranges do not overlap.
Body fragment after validating live source/destination objects and their extents. memmove supports permitted overlap. This snippet does not permit using arbitrary non-NULL pointers or impose string-termination semantics on a byte copy.
if ((copy_size_bytes > destination_capacity_bytes) ||
(copy_size_bytes > source_size_bytes))
{
ret = -ERANGE;
goto function_output;
}
if (copy_size_bytes != 0u)
memmove(destination, source, copy_size_bytes);
Action: ban-pattern. Canonical entry.
validated range-copy wrapper
Body fragment after validating live source/destination objects and their extents. memmove supports permitted overlap. This snippet does not permit using arbitrary non-NULL pointers or impose string-termination semantics on a byte copy.
if ((copy_size_bytes > destination_capacity_bytes) ||
(copy_size_bytes > source_size_bytes))
{
ret = -ERANGE;
goto function_output;
}
if (copy_size_bytes != 0u)
memmove(destination, source, copy_size_bytes);
Action: ban-pattern. Canonical entry.
validated range-move wrapper
Body fragment after validating live source/destination objects and their extents. memmove supports permitted overlap. This snippet does not permit using arbitrary non-NULL pointers or impose string-termination semantics on a byte copy.
if ((copy_size_bytes > destination_capacity_bytes) ||
(copy_size_bytes > source_size_bytes))
{
ret = -ERANGE;
goto function_output;
}
if (copy_size_bytes != 0u)
memmove(destination, source, copy_size_bytes);
Action: ban-pattern. Canonical entry.
Use a qualified explicit-erasure primitive; account for copies and compiler/runtime behavior.
A qualified security primitive must prevent removal of the erase on the named toolchain and cover relevant copies. The injected call documents the boundary; this declaration is not a constant-time or erase implementation.
ret = erase_secret(security_context, secret, secret_size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project zeroing or secure-zero wrapper
Ordinary byte initialization after validating the writable extent, not secret erasure and not semantic initialization of arbitrary pointer/floating objects. Use semantic aggregate initialization for such objects.
if (size_bytes != 0u)
memset(byte_buffer, 0, size_bytes);
Action: ban-pattern. Canonical entry.
Use a reviewed constant-time primitive for the stated equal-length secret contract.
Equal-length secret buffers and their extents are validated before the call. The security adapter owns the constant-time contract; ordinary memcmp or a guessed loop is not substituted for that evidence.
ret = equal_secret(security_context, left, right, size_bytes, &is_equal);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
field-by-field comparison
Both validated records have value semantics for these fields. Compare every meaningful field explicitly; do not compare struct padding, locks, pointer ownership or resource identity as raw bytes.
is_equal =
(left->object_id == right->object_id) && (left->state == right->state);
Action: ban. Canonical entry.
validated range-copy or range-move wrapper
Body fragment after validating live source/destination objects and their extents. memmove supports permitted overlap. This snippet does not permit using arbitrary non-NULL pointers or impose string-termination semantics on a byte copy.
if ((copy_size_bytes > destination_capacity_bytes) ||
(copy_size_bytes > source_size_bytes))
{
ret = -ERANGE;
goto function_output;
}
if (copy_size_bytes != 0u)
memmove(destination, source, copy_size_bytes);
Action: ban. Canonical entry.
field or byte comparison wrapper as appropriate
Non-secret byte comparison with validated extents. ret and all variables are declared at function entry. Early loop termination is expressed in the condition. This is deliberately not a constant-time secret comparison.
is_equal = true;
for (index = 0u; (index < size_bytes) && is_equal; index++)
{
is_equal = (left[index] == right[index]);
}
Action: ban. Canonical entry.
bounded automatic storage or project allocation policy
scratch belongs at function entry and the selected profile must budget its 256 bytes. The number is an illustrative fixed capacity, not a universal stack allowance. Variable alloca/VLA storage is not introduced.
unsigned char scratch[256] = { 0 };
if (requested_bytes > sizeof(scratch))
{
ret = -ENOSPC;
goto function_output;
}
Action: ban. Canonical entry.
bounded automatic storage or project allocation policy
scratch belongs at function entry and the selected profile must budget its 256 bytes. The number is an illustrative fixed capacity, not a universal stack allowance. Variable alloca/VLA storage is not introduced.
unsigned char scratch[256] = { 0 };
if (requested_bytes > sizeof(scratch))
{
ret = -ENOSPC;
goto function_output;
}
Action: review. Canonical entry.
preallocated storage, pool, arena, or explicit failure policy
Explicit bounded pool port: initialization precedes the critical phase, exhaustion is defined, and worst-case latency/stack evidence is target-specific. The callback name does not prove that its implementation avoids heap allocation.
ret = acquire_slot(pool_context, &slot);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
preallocated storage, pool, arena, or explicit failure policy
Explicit bounded pool port: initialization precedes the critical phase, exhaustion is defined, and worst-case latency/stack evidence is target-specific. The callback name does not prove that its implementation avoids heap allocation.
ret = acquire_slot(pool_context, &slot);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
Handle zero explicitly; positive-size failure preserves the owner; invalidate aliases on success.
Owned-allocation fragment. Validate size and allocator family first; declarations are at function entry. The resize contract preserves the old allocation on positive-size failure. On success all old aliases are invalid. The API explicitly chooses release-on-zero rather than calling native realloc with zero.
if (new_size_bytes == 0u)
{
release_owned(memory_context, allocation);
allocation = (unsigned char *)(NULL);
goto function_output;
}
replacement = (unsigned char *)resize_owned(memory_context, allocation,
new_size_bytes);
if (replacement == (unsigned char *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
allocation = replacement;
Action: ban-pattern. Canonical entry.
project ownership/release API
Only the allocator/owner whose release contract owns this base pointer may release it. Nulling this variable does not clear aliases or solve concurrent reclamation.
release_owned(memory_context, allocation); allocation = (unsigned char *)(NULL);
Action: ban. Canonical entry.
fixed argument-vector process wrapper
Approved process adapter maps an authorized executable identity to its actual path and constructs platform arguments without a shell. Windows quoting, controlled environment and handle inheritance need their own implementation contract. Validation includes who may invoke this operation.
ret = spawn_process(process_context, executable_id, arguments, argument_count,
environment_id, &process_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
fixed argument-vector process wrapper
Approved process adapter maps an authorized executable identity to its actual path and constructs platform arguments without a shell. Windows quoting, controlled environment and handle inheritance need their own implementation contract. Validation includes who may invoke this operation.
ret = spawn_process(process_context, executable_id, arguments, argument_count,
environment_id, &process_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
absolute-path execution wrapper with controlled environment
Approved process adapter maps an authorized executable identity to its actual path and constructs platform arguments without a shell. Windows quoting, controlled environment and handle inheritance need their own implementation contract. Validation includes who may invoke this operation.
ret = spawn_process(process_context, executable_id, arguments, argument_count,
environment_id, &process_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
absolute-path execution wrapper with controlled environment
Approved process adapter maps an authorized executable identity to its actual path and constructs platform arguments without a shell. Windows quoting, controlled environment and handle inheritance need their own implementation contract. Validation includes who may invoke this operation.
ret = spawn_process(process_context, executable_id, arguments, argument_count,
environment_id, &process_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
Use documented Windows argument quoting, executable identity, environment, and handle inheritance rules.
Approved process adapter maps an authorized executable identity to its actual path and constructs platform arguments without a shell. Windows quoting, controlled environment and handle inheritance need their own implementation contract. Validation includes who may invoke this operation.
ret = spawn_process(process_context, executable_id, arguments, argument_count,
environment_id, &process_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
Authorize the actual loaded object, path, ABI, provenance, and lifetime through the loader owner.
Loader owner verifies the actual artifact, search-path policy, authenticity where required, ABI and lifetime. An authorized pathname string alone does not close path-replacement races or make loaded native code isolated.
ret = load_authorized(loader_context, artifact_id, expected_abi,
&module_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
Authorize the actual loaded object, path, ABI, provenance, and lifetime through the loader owner.
Loader owner verifies the actual artifact, search-path policy, authenticity where required, ABI and lifetime. An authorized pathname string alone does not close path-replacement races or make loaded native code isolated.
ret = load_authorized(loader_context, artifact_id, expected_abi,
&module_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
secure temporary-file wrapper
Adapter creates and opens the object atomically with restrictive permissions and explicit cleanup/inheritance policy. Returning a supposedly unique name before opening is not sufficient.
ret = create_temporary(file_context, approved_directory_id, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
secure temporary-file wrapper
Adapter creates and opens the object atomically with restrictive permissions and explicit cleanup/inheritance policy. Returning a supposedly unique name before opening is not sufficient.
ret = create_temporary(file_context, approved_directory_id, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
secure temporary-file wrapper
Adapter creates and opens the object atomically with restrictive permissions and explicit cleanup/inheritance policy. Returning a supposedly unique name before opening is not sufficient.
ret = create_temporary(file_context, approved_directory_id, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
secure temporary-file wrapper
Adapter creates and opens the object atomically with restrictive permissions and explicit cleanup/inheritance policy. Returning a supposedly unique name before opening is not sufficient.
ret = create_temporary(file_context, approved_directory_id, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project path wrapper with root and mode policy
File adapter validates the object opened using the platform root/descriptor and link-resolution policy. Do not authorize with access/stat/realpath and assume a later pathname use refers to the same object. Permission/ownership changes need the operation-specific authorization.
ret = open_authorized(file_context, root_handle, relative_path,
operation_policy, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project path wrapper with descriptor-based workflow
File adapter validates the object opened using the platform root/descriptor and link-resolution policy. Do not authorize with access/stat/realpath and assume a later pathname use refers to the same object. Permission/ownership changes need the operation-specific authorization.
ret = open_authorized(file_context, root_handle, relative_path,
operation_policy, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
attempt operation directly and handle failure
File adapter validates the object opened using the platform root/descriptor and link-resolution policy. Do not authorize with access/stat/realpath and assume a later pathname use refers to the same object. Permission/ownership changes need the operation-specific authorization.
ret = open_authorized(file_context, root_handle, relative_path,
operation_policy, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
descriptor-based validation workflow
File adapter validates the object opened using the platform root/descriptor and link-resolution policy. Do not authorize with access/stat/realpath and assume a later pathname use refers to the same object. Permission/ownership changes need the operation-specific authorization.
ret = open_authorized(file_context, root_handle, relative_path,
operation_policy, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project permission wrapper with allowlist
File adapter validates the object opened using the platform root/descriptor and link-resolution policy. Do not authorize with access/stat/realpath and assume a later pathname use refers to the same object. Permission/ownership changes need the operation-specific authorization.
ret = open_authorized(file_context, root_handle, relative_path,
operation_policy, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project ownership wrapper with allowlist
File adapter validates the object opened using the platform root/descriptor and link-resolution policy. Do not authorize with access/stat/realpath and assume a later pathname use refers to the same object. Permission/ownership changes need the operation-specific authorization.
ret = open_authorized(file_context, root_handle, relative_path,
operation_policy, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
checked I/O wrapper
I/O port specifies read versus write, partial completion, interruption, EOF, zero progress and bounded retry. Preserve completed progress on errors where the contract permits it; never assume requested_bytes were transferred.
ret = transfer(io_context, buffer, requested_bytes, &completed_bytes);
if (completed_bytes > requested_bytes)
{
ret = -EIO;
goto function_output;
}
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
checked I/O wrapper
I/O port specifies read versus write, partial completion, interruption, EOF, zero progress and bounded retry. Preserve completed progress on errors where the contract permits it; never assume requested_bytes were transferred.
ret = transfer(io_context, buffer, requested_bytes, &completed_bytes);
if (completed_bytes > requested_bytes)
{
ret = -EIO;
goto function_output;
}
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
checked write wrapper
I/O port specifies read versus write, partial completion, interruption, EOF, zero progress and bounded retry. Preserve completed progress on errors where the contract permits it; never assume requested_bytes were transferred.
ret = transfer(io_context, buffer, requested_bytes, &completed_bytes);
if (completed_bytes > requested_bytes)
{
ret = -EIO;
goto function_output;
}
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
checked read wrapper
I/O port specifies read versus write, partial completion, interruption, EOF, zero progress and bounded retry. Preserve completed progress on errors where the contract permits it; never assume requested_bytes were transferred.
ret = transfer(io_context, buffer, requested_bytes, &completed_bytes);
if (completed_bytes > requested_bytes)
{
ret = -EIO;
goto function_output;
}
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
checked write wrapper
I/O port specifies read versus write, partial completion, interruption, EOF, zero progress and bounded retry. Preserve completed progress on errors where the contract permits it; never assume requested_bytes were transferred.
ret = transfer(io_context, buffer, requested_bytes, &completed_bytes);
if (completed_bytes > requested_bytes)
{
ret = -EIO;
goto function_output;
}
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
project cryptographic-random wrapper
Qualified cryptographic-random provider, including startup, entropy readiness and failure policy. No predictable time seed or ordinary PRNG fallback is allowed for security output.
ret = random_bytes(random_context, destination, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
project cryptographic-random wrapper
Qualified cryptographic-random provider, including startup, entropy readiness and failure policy. No predictable time seed or ordinary PRNG fallback is allowed for security output.
ret = random_bytes(random_context, destination, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
project cryptographic-random wrapper
Qualified cryptographic-random provider, including startup, entropy readiness and failure policy. No predictable time seed or ordinary PRNG fallback is allowed for security output.
ret = random_bytes(random_context, destination, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
project cryptographic-random wrapper
Qualified cryptographic-random provider, including startup, entropy readiness and failure policy. No predictable time seed or ordinary PRNG fallback is allowed for security output.
ret = random_bytes(random_context, destination, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
project cryptographic-random wrapper
Qualified cryptographic-random provider, including startup, entropy readiness and failure policy. No predictable time seed or ordinary PRNG fallback is allowed for security output.
ret = random_bytes(random_context, destination, size_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
validated configuration wrapper
Composition owns environment, working directory and process-wide defaults. Ordinary libraries consume validated explicit configuration instead of changing global process state. File-creation permissions belong in the file adapter.
ret = read_configuration(config_context, setting_id, &setting);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project environment wrapper
Composition owns environment, working directory and process-wide defaults. Ordinary libraries consume validated explicit configuration instead of changing global process state. File-creation permissions belong in the file adapter.
ret = read_configuration(config_context, setting_id, &setting);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project environment wrapper
Composition owns environment, working directory and process-wide defaults. Ordinary libraries consume validated explicit configuration instead of changing global process state. File-creation permissions belong in the file adapter.
ret = read_configuration(config_context, setting_id, &setting);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project environment wrapper
Composition owns environment, working directory and process-wide defaults. Ordinary libraries consume validated explicit configuration instead of changing global process state. File-creation permissions belong in the file adapter.
ret = read_configuration(config_context, setting_id, &setting);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
absolute-path workflow
Composition owns environment, working directory and process-wide defaults. Ordinary libraries consume validated explicit configuration instead of changing global process state. File-creation permissions belong in the file adapter.
ret = read_configuration(config_context, setting_id, &setting);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project file-creation wrapper
Composition owns environment, working directory and process-wide defaults. Ordinary libraries consume validated explicit configuration instead of changing global process state. File-creation permissions belong in the file adapter.
ret = read_configuration(config_context, setting_id, &setting);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project signal wrapper using defined handler policy
Platform adapter owns handler registration and its restricted execution contract. Handler bodies use only permitted signal-safe operations; this registration snippet is not a handler.
ret = install_signal_policy(signal_context, policy_id);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
structured error propagation
Normal module failure returns through its cleanup path. A platform-approved fatal policy must be explicit and confined to its stated scope; nonlocal jumps do not bypass resource cleanup.
if (operation_failed)
{
ret = -EIO;
goto function_output;
}
Action: review. Canonical entry.
project process-spawn wrapper
Approved process adapter maps an authorized executable identity to its actual path and constructs platform arguments without a shell. Windows quoting, controlled environment and handle inheritance need their own implementation contract. Validation includes who may invoke this operation. The process owner handles multithreaded fork restrictions and the child path before exec.
ret = spawn_process(process_context, executable_id, arguments, argument_count,
environment_id, &process_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
cooperative cancellation
Cooperative stop at an invariant-preserving point; function_output releases only acquired resources. This must not abandon locks, transferred objects or a partially committed transaction.
ret = stop_requested(control_context, &is_stopping);
if (ret != EXIT_SUCCESS)
goto function_output;
if (is_stopping)
goto function_output;
Action: ban (new security code). Canonical entry.
approved password-hashing wrapper
Qualified password-hashing adapter owns algorithm, salt, cost parameters, encoding and migration policy. A legacy crypt alias is not approved merely because it sits behind this port.
ret = hash_password(security_context, password, password_size_bytes, policy_id,
output, output_capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
approved cryptographic digest wrapper
Security policy chooses the digest for the actual use case; non-security checksums have a different contract. The adapter verifies output capacity and reports failure explicitly.
ret = digest_message(security_context, approved_algorithm_id, input,
input_size_bytes, digest, digest_capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
approved cryptographic digest wrapper
Security policy chooses the digest for the actual use case; non-security checksums have a different contract. The adapter verifies output capacity and reports failure explicitly.
ret = digest_message(security_context, approved_algorithm_id, input,
input_size_bytes, digest, digest_capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban (new security code). Canonical entry.
approved cipher wrapper
Approved authenticated-encryption adapter owns nonce uniqueness, key lifecycle, tag handling and output sizes. This call is not a cryptographic implementation or permission to reuse a nonce.
ret = seal_message(security_context, key_id, nonce, plaintext,
plaintext_size_bytes, associated_data,
associated_data_size_bytes, output, output_capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban (new security code). Canonical entry.
approved cipher wrapper
Approved authenticated-encryption adapter owns nonce uniqueness, key lifecycle, tag handling and output sizes. This call is not a cryptographic implementation or permission to reuse a nonce.
ret = seal_message(security_context, key_id, nonce, plaintext,
plaintext_size_bytes, associated_data,
associated_data_size_bytes, output, output_capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
Use an approved authenticated-encryption construction and its complete nonce/key protocol.
Approved authenticated-encryption adapter owns nonce uniqueness, key lifecycle, tag handling and output sizes. This call is not a cryptographic implementation or permission to reuse a nonce.
ret = seal_message(security_context, key_id, nonce, plaintext,
plaintext_size_bytes, associated_data,
associated_data_size_bytes, output, output_capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
Preserve EOF; convert a byte through unsigned char before promotion.
input_character is an int from a byte-input API, preserving EOF; result is declared at function entry. Include <ctype.h> and <stdio.h>. A separate encoding/locale policy determines the intended classification or conversion.
if (input_character != EOF)
result = isalpha((unsigned char)input_character);
Action: ban-pattern. Canonical entry.
Preserve EOF; convert a byte through unsigned char before promotion.
input_character is an int from a byte-input API, preserving EOF; result is declared at function entry. Include <ctype.h> and <stdio.h>. A separate encoding/locale policy determines the intended classification or conversion.
if (input_character != EOF)
result = isdigit((unsigned char)input_character);
Action: ban-pattern. Canonical entry.
Preserve EOF; convert a byte through unsigned char before promotion.
input_character is an int from a byte-input API, preserving EOF; result is declared at function entry. Include <ctype.h> and <stdio.h>. A separate encoding/locale policy determines the intended classification or conversion.
if (input_character != EOF)
result = tolower((unsigned char)input_character);
Action: ban-pattern. Canonical entry.
Preserve EOF; convert a byte through unsigned char before promotion.
input_character is an int from a byte-input API, preserving EOF; result is declared at function entry. Include <ctype.h> and <stdio.h>. A separate encoding/locale policy determines the intended classification or conversion.
if (input_character != EOF)
result = toupper((unsigned char)input_character);
Action: ban-pattern. Canonical entry.
Compare relationally and return negative/zero/positive without overflowing subtraction.
Comparator-body fragment after accessing valid values. ret is the comparator result under its required domain contract; the final function_output returns ret. Relational comparison avoids overflow from subtracting the two values.
if (left_value < right_value)
ret = -1;
else if (left_value > right_value)
{
ret = 1;
}
else
ret = 0;
goto function_output;
Action: ban-pattern. Canonical entry.
runtime validation with explicit error path
Runtime validation of externally influenced length. Assertions may still check internal invariants but cannot replace this rejection in release builds.
if (length_bytes > capacity_bytes)
{
ret = -ERANGE;
goto function_output;
}
Action: review. Canonical entry.
error propagation or configured fatal policy
Normal module failure returns through its cleanup path. A platform-approved fatal policy must be explicit and confined to its stated scope; nonlocal jumps do not bypass resource cleanup.
if (operation_failed)
{
ret = -EIO;
goto function_output;
}
Action: review. Canonical entry.
error propagation or configured fatal policy
Normal module failure returns through its cleanup path. A platform-approved fatal policy must be explicit and confined to its stated scope; nonlocal jumps do not bypass resource cleanup.
if (operation_failed)
{
ret = -EIO;
goto function_output;
}
Action: review. Canonical entry.
project logging/error API
Explicit error-description port with bounded caller storage and thread/locale policy. Report through the configured diagnostic owner; do not silently print to standard streams.
ret = describe_error(error_context, error_code, buffer, buffer_capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project error-string wrapper
Explicit error-description port with bounded caller storage and thread/locale policy. Report through the configured diagnostic owner; do not silently print to standard streams.
ret = describe_error(error_context, error_code, buffer, buffer_capacity_bytes);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
project time-format wrapper
Time adapter owns timezone, locale, range and thread-safe storage. It does not expose native shared static result buffers; durations use a separate monotonic domain.
ret = format_time(time_context, timestamp, time_policy_id, buffer,
buffer_capacity_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
project time-format wrapper
Time adapter owns timezone, locale, range and thread-safe storage. It does not expose native shared static result buffers; durations use a separate monotonic domain.
ret = format_time(time_context, timestamp, time_policy_id, buffer,
buffer_capacity_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project time wrapper
Time adapter owns timezone, locale, range and thread-safe storage. It does not expose native shared static result buffers; durations use a separate monotonic domain.
ret = format_time(time_context, timestamp, time_policy_id, buffer,
buffer_capacity_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project time wrapper
Time adapter owns timezone, locale, range and thread-safe storage. It does not expose native shared static result buffers; durations use a separate monotonic domain.
ret = format_time(time_context, timestamp, time_policy_id, buffer,
buffer_capacity_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
Validate the object opened; canonicalization alone does not prevent link/check-use races.
File adapter validates the object opened using the platform root/descriptor and link-resolution policy. Do not authorize with access/stat/realpath and assume a later pathname use refers to the same object. Permission/ownership changes need the operation-specific authorization.
ret = open_authorized(file_context, root_handle, relative_path,
operation_policy, &owned_file_handle);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
ownership, bounds, and API contract validation
The base object must already have a proven live lifetime, extent and access permission under its owner contract. Range checks do not validate arbitrary pointers; probing readability/writability is not an ownership proof.
if (offset_bytes > capacity_bytes)
{
ret = -ERANGE;
goto function_output;
}
if (length_bytes > (capacity_bytes - offset_bytes))
{
ret = -ERANGE;
goto function_output;
}
Action: ban. Canonical entry.
ownership, bounds, and API contract validation
The base object must already have a proven live lifetime, extent and access permission under its owner contract. Range checks do not validate arbitrary pointers; probing readability/writability is not an ownership proof.
if (offset_bytes > capacity_bytes)
{
ret = -ERANGE;
goto function_output;
}
if (length_bytes > (capacity_bytes - offset_bytes))
{
ret = -ERANGE;
goto function_output;
}
Action: review. Canonical entry.
project path wrapper with explicit capacities
Bounded path construction/parsing with explicit capacities and encoding. Constructing a path does not authorize opening it; the actual-object access policy remains separate.
ret = build_path(path_context, path_components, component_count, output,
output_capacity_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project path wrapper with explicit capacities
Bounded path construction/parsing with explicit capacities and encoding. Constructing a path does not authorize opening it; the actual-object access policy remains separate.
ret = build_path(path_context, path_components, component_count, output,
output_capacity_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: review. Canonical entry.
project path wrapper with explicit capacities
Bounded path construction/parsing with explicit capacities and encoding. Constructing a path does not authorize opening it; the actual-object access policy remains separate.
ret = build_path(path_context, path_components, component_count, output,
output_capacity_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
bounded line-input wrapper
Injected bounded-input port: capacity_chars includes any required terminator. Its contract distinguishes EOF, truncation and I/O failure, uses the selected character/encoding domain, and never writes past capacity. Declarations and required callback validation precede this body fragment.
ret = read_line(input_context, buffer, capacity_chars, &length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
bounded copy wrapper with capacity and status
Injected copy port: the actual signature uses the selected char, wchar_t or platform character type. Capacity units and termination/truncation semantics are explicit; validate the readable source extent. A renamed unbounded strcpy is not an acceptable implementation.
ret = copy_text(copy_context, destination, destination_capacity_chars, source,
source_length_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban. Canonical entry.
bounded formatting wrapper with checked result
Injected bounded formatter: its implementation must check native formatting failure and truncation and handle va_list copies when applicable. ISO swprintf and legacy platform swprintf signatures must not be confused. Output units and termination are part of this port, not guessed from the native API name.
ret = format_value(format_context, destination, destination_capacity_chars,
value, &written_chars);
if (ret != EXIT_SUCCESS)
goto function_output;
Action: ban-pattern. Canonical entry.
checked allocation wrapper or explicit error path
size_bytes is a validated nonzero size under the allocator contract. allocation is declared as a typed NULL at function entry; release through the same allocator family.
allocation = (unsigned char *)allocate(memory_context, size_bytes);
if (allocation == (unsigned char *)(NULL))
{
ret = -ENOMEM;
goto function_output;
}
Action: ban-pattern. Canonical entry.
checked multiplication helper
Inside the approved checked-arithmetic implementation, with size_t operands and <stdint.h>. Ordinary modules use the approved helper/port. The result still needs the API zero-size and maximum-budget policy.
if ((element_size_bytes != 0u) &&
(element_count > (SIZE_MAX / element_size_bytes)))
{
ret = -ERANGE;
goto function_output;
}
allocation_bytes = element_count * element_size_bytes;
Action: ban-pattern. Canonical entry.
checked addition helper
Inside the checked-arithmetic owner. The capacity comparison follows the checked sum; arithmetic correctness does not imply enough writable storage.
if (append_bytes > (SIZE_MAX - used_bytes))
{
ret = -ERANGE;
goto function_output;
}
required_bytes = used_bytes + append_bytes;
Action: ban-pattern. Canonical entry.
checked conversion helper
wide_count is uint32_t; narrow_count is initialized to zero at function entry. Signed inputs also require a negative-value check before unsigned conversion.
if (wide_count > UINT16_MAX)
{
ret = -ERANGE;
goto function_output;
}
narrow_count = (uint16_t)wide_count;
Action: ban-pattern. Canonical entry.
check the return value and handle failure explicitly
The configured security port has an explicit deny/failure contract. Mutate protected state only after success, under the same object/state consistency contract.
ret = authorize(security_context, principal, operation, object_id);
if (ret != EXIT_SUCCESS)
goto function_output;
The three guides share one policy and use stable rule identifiers for cross-references.