Skip to content

Commit cd9f5d6

Browse files
authored
Merge pull request #499 from henrygab/safer_macros
type-safe array macros
2 parents 9a7034b + 70c947d commit cd9f5d6

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

cores/nRF5/common_func.h

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,48 @@
3737
#ifndef _COMMON_FUNC_H_
3838
#define _COMMON_FUNC_H_
3939

40+
4041
#ifdef __cplusplus
41-
extern "C" {
42+
// namespace and templates must be outside the `extern "C"` declaration...
43+
namespace ADAFRUIT_DETAIL
44+
{
45+
template <typename T, size_t N>
46+
constexpr size_t arrcount_fails_if_not_array(T const (&)[N]) noexcept
47+
{
48+
return N;
49+
}
50+
}
51+
extern "C" {
52+
#define arrcount(arr) ADAFRUIT_DETAIL::arrcount_fails_if_not_array(arr)
53+
#define ADA_STATIC_ASSERT(const_expr, message) static_assert(const_expr, message)
54+
#elif __STDC_VERSION__ >= 201112L
55+
// Even C can have type-safety for equivalent of ARRAY_SIZE() macro, when using GCC (which this BSP does)
56+
#define __ADA_COMPATIBLE_TYPES(a,b) __builtin_types_compatible_p(typeof(a), typeof(b)) // GCC extensions
57+
#define __ADA_BUILD_ERROR_IF_NONZERO(x) (sizeof(struct { int:-!!(x)*0x1ee7;})) // if x is zero, reports "error: negative width in bit-field '<anonymous>'"
58+
#define __ADA_MUST_BE_ARRAY(x) __ADA_BUILD_ERROR_IF_NONZERO(__ADA_COMPATIBLE_TYPES((x), &(*x)))
59+
#define ADA_STATIC_ASSERT(const_expr, message) _Static_assert(const_expr, message)
60+
#define arrcount(_arr) ( (sizeof(_arr) / sizeof((_arr)[0])) + __ADA_MUST_BE_ARRAY(_arr) ) // compile-time error if not an array
61+
#else
62+
#error "C Compiler must support at least C11"
63+
#endif
64+
65+
#define ADA_STRING(x) #x ///< stringify without expand
66+
#define ADA_XSTRING(x) ADA_STRING(x) ///< expand then stringify
67+
#define ADA_STRCAT(a, b) a##b ///< concat without expand
68+
#define ADA_XSTRCAT(a, b) ADA_STRCAT(a, b) ///< expand then concat
69+
70+
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
71+
#define ADA_COUNTER __COUNTER__
72+
#else
73+
#define ADA_COUNTER __LINE__
4274
#endif
4375

4476
#define COMMENT_OUT(x)
4577

4678
#define memclr(buffer, size) memset(buffer, 0, size)
4779
#define varclr(_var) memclr(_var, sizeof(*(_var)))
48-
#define arrclr(_arr) memclr(_arr, sizeof(_arr))
80+
#define arrclr(_arr) memclr(_arr, sizeof(_arr[0]) * arrcount(_arr)) // adds type-safety
4981

50-
#define arrcount(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
5182

5283
#define __swap32(x) __REV(x) ///< built-in function to swap Endian of 32-bit number
5384
#define __swap16(u16) ((uint16_t) __REV16(u16)) ///< built-in function to swap Endian of 16-bit number
@@ -117,9 +148,9 @@
117148
const char* dbg_err_str(int32_t err_id); // TODO move to other place
118149

119150
#if __cplusplus
120-
#define PRINTF ::printf
151+
#define PRINTF ::printf
121152
#else
122-
#define PRINTF printf
153+
#define PRINTF printf
123154
#endif
124155

125156

@@ -143,7 +174,7 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
143174

144175
#define PRINT_LOCATION() PRINTF("%s: %d:\n", __PRETTY_FUNCTION__, __LINE__)
145176
#define PRINT_MESS(x) PRINTF("%s: %d: %s \n" , __FUNCTION__, __LINE__, (char*)(x))
146-
#define PRTNT_HEAP() if (CFG_DEBUG >= 3) PRINTF("\n%s: %d: Heap free: %d\n", __FUNCTION__, __LINE__, util_heap_get_free_size())
177+
#define PRINT_HEAP() if (CFG_DEBUG >= 3) PRINTF("\n%s: %d: Heap free: %d\n", __FUNCTION__, __LINE__, util_heap_get_free_size())
147178
#define PRINT_STR(x) PRINTF("%s: %d: " #x " = %s\n" , __FUNCTION__, __LINE__, (char*)(x) )
148179
#define PRINT_INT(x) PRINTF("%s: %d: " #x " = %ld\n" , __FUNCTION__, __LINE__, (uint32_t) (x) )
149180
#define PRINT_FLOAT(x) PRINTF("%s: %d: " #x " = %f\n" , __FUNCTION__, __LINE__, (float) (x) )
@@ -182,7 +213,7 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
182213

183214
#define PRINT_LOCATION()
184215
#define PRINT_MESS(x)
185-
#define PRTNT_HEAP()
216+
#define PRINT_HEAP()
186217
#define PRINT_STR(x)
187218
#define PRINT_INT(x)
188219
#define PRINT_HEX(x)

0 commit comments

Comments
 (0)