assert_cc(sizeof(dummy_t) == 0);
+/* A little helper for subtracting 1 off a pointer in a safe UB-free way. This is intended to be used for for
+ * loops that count down from a high pointer until some base. A naive loop would implement this like this:
+ *
+ * for (p = end-1; p >= base; p--) …
+ *
+ * But this is not safe because p before the base is UB in C. With this macro the loop becomes this instead:
+ *
+ * for (p = PTR_SUB1(end, base); p; p = PTR_SUB1(p, base)) …
+ *
+ * And is free from UB! */
+#define PTR_SUB1(p, base) \
+ ({ \
+ typeof(p) _q = (p); \
+ _q && _q > (base) ? &_q[-1] : NULL; \
+ })
+
#include "log.h"
assert_se(DECIMAL_STR_MAX(uint64_t) == DECIMAL_STR_WIDTH(u64_longest)+1);
}
+TEST(PTR_SUB1) {
+ static const uint64_t x[4] = { 2, 3, 4, 5 };
+ const uint64_t *p;
+
+ p = x + ELEMENTSOF(x)-1;
+ assert_se(*p == 5);
+
+ p = PTR_SUB1(p, x);
+ assert_se(*p == 4);
+
+ p = PTR_SUB1(p, x);
+ assert_se(*p == 3);
+
+ p = PTR_SUB1(p, x);
+ assert_se(*p == 2);
+
+ p = PTR_SUB1(p, x);
+ assert_se(!p);
+
+ p = PTR_SUB1(p, x);
+ assert_se(!p);
+}
+
DEFINE_TEST_MAIN(LOG_INFO);