safemath
Unchecked size and offset arithmetic can wrap before allocation or bounds validation.
A header-only bool-returning API checks size addition, subtraction, multiplication, offsets and alignment without changing output on failure.
Checked helpers that leave outputs alone on failure
safemath is a header-only C/C++ utility for overflow-safe size arithmetic used in allocation sizing, buffer bounds and alignment. Every result-writing API returns bool; success writes the output and failure leaves the caller's output unchanged.
Add, subtract and multiply with explicit checks
sm_add, sm_sub and sm_mul handle size_t values. The implementation can select compiler overflow builtins when available or use a portable arithmetic path. SAFEMATH_FORCE_PORTABLE selects the latter; SAFEMATH_FORCE_BUILTINS requests builtins and fails compilation when the required support is absent. Defining both modes is a compile-time error.
size_t bytes = 0u;
if (!sm_array_bytes(&bytes, count, sizeof(struct record))) {
return false; /* bytes remains unchanged on failure */
}
allocate(bytes);The API uses standard C headers and has no third-party runtime dependency. Optional SAFEMATH_NODISCARD attributes help compilers warn when a result is ignored.
Compose multiplication and addition without wrapping
sm_array_bytes(out, count, elem_size) checks multiplication. sm_alloc_bytes(out, count, elem_size, extra) checks both the array product and the extra-byte sum. A mathematically valid zero-sized element calculation returns zero; it is not treated as an error by itself.
These functions calculate a size; they do not allocate memory, validate a particular allocator's policy, or make a caller's later indexing safe by themselves.
One-past-end can be valid without being dereferenceable
sm_offset_add(out, base, offset, limit) first checks that the sum fits in size_t, then requires the result to be no greater than limit. Equality is valid and represents an exclusive end. That result may mark the boundary after the final element; it must not be dereferenced as an array index.
Validate alignment before rounding up
sm_is_pow2 returns true only for non-zero powers of two. sm_align_up requires such an alignment. sm_align_up_bytes combines checked array sizing and alignment. Invalid alignment and arithmetic overflow return false while preserving the output value.
Alignment helpers calculate a byte count. They do not guarantee that the eventual allocator returns an address with matching alignment; pointer alignment is the responsibility of the allocation interface.
Portable path and builtin path are checked separately
The repository verification log records C99 and C++11 tests, CMake/CTest, a package consumer, and auto/forced-portable paths. It also records MSVC, GCC and Clang host execution, static analysis and ARM Cortex-M0/M4/M7 smoke builds. A forced-builtin MSVC compile is expected to fail clearly because that compiler lacks the required builtins; that is feature detection, not a library test failure.
These are repository-recorded host and compile results. They are not evidence of allocation behavior in an application or correctness of every downstream bounds calculation.
cmake -S . -B build -DSAFEMATH_BUILD_TESTS=ON \
-DSAFEMATH_BUILD_PROPERTY_TESTS=ON -DSAFEMATH_STRICT_WARNINGS=ON
cmake --build build
ctest --test-dir build --output-on-failureUseful arithmetic checks; no automatic safety proof
- The boolean result does not distinguish overflow, underflow, invalid input and unsupported mode.
- Every result must be checked; ignoring false can make stale output look valid.
- Successful offset equality means one-past-end, not an accessible element.
- The helper does not own memory or validate later pointer use.
- Callers still need correct object counts, domains, lifetime and allocator alignment.