solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
Loading...
Searching...
No Matches
ckdint.h
Go to the documentation of this file.
1
6#ifndef SOLIDC_CKDINT_H
7#define SOLIDC_CKDINT_H
8
9#include <stdbool.h>
10#include <stddef.h>
11
12/*
13 * Detect if the compiler supports GCC/Clang style built-in overflow checks.
14 * GCC 5+ and Clang 3.8+ support these.
15 */
16#if defined(__has_builtin)
17#if __has_builtin(__builtin_add_overflow)
18#define SOLIDC_USE_BUILTINS
19#endif
20#elif defined(__GNUC__) && (__GNUC__ >= 5)
21#define SOLIDC_USE_BUILTINS
22#endif
23
24#ifdef SOLIDC_USE_BUILTINS
25
26/*
27 * Generic Macros: These work for int, long, size_t, etc.
28 * Returns true (1) if overflow occurred, false (0) otherwise.
29 */
30#define ckd_add(r, a, b) __builtin_add_overflow((a), (b), (r))
31#define ckd_sub(r, a, b) __builtin_sub_overflow((a), (b), (r))
32#define ckd_mul(r, a, b) __builtin_mul_overflow((a), (b), (r))
33
34#else
35
36/*
37 * Fallback (MSVC / ANSI C):
38 * Portable implementations for size_t (unsigned arithmetic).
39 */
40
41static inline bool ckd_add(size_t* r, size_t a, size_t b) {
42 *r = a + b;
43 return *r < a;
44}
45
46static inline bool ckd_sub(size_t* r, size_t a, size_t b) {
47 *r = a - b;
48 return *r > a;
49}
50
51static inline bool ckd_mul(size_t* r, size_t a, size_t b) {
52 if (a == 0 || b == 0) {
53 *r = 0;
54 return false;
55 }
56 *r = a * b;
57 return (*r / a) != b;
58}
59
60#endif /* SOLIDC_USE_BUILTINS */
61
62#undef SOLIDC_USE_BUILTINS
63
64#endif /* SOLIDC_CKDINT_H */