sys: util.h: remove template implementation of ARRAY_SIZE

This was added because GNU G++ doesn't support the built-in function
used to produce a compile-time error when invalid parameters are
passed to the macro imlementation.  The template implementation does
not work on declarations like this:

  mytype array[] = { ... }

because it requires an explicit size for the template parameter.

Remove the template specialization, and support C++ with a version of
the macro that doesn't involve references to undefined builtins.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2020-05-25 09:51:10 -05:00 committed by Carles Cufí
commit fe74218956

View file

@ -48,29 +48,31 @@ extern "C" {
/* Evaluates to 0 if cond is true-ish; compile error otherwise */ /* Evaluates to 0 if cond is true-ish; compile error otherwise */
#define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1) #define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
/* Evaluates to 0 if array is an array; compile error if not array (e.g. #if defined(__cplusplus)
* pointer)
/* Evaluates to number of elements in an array. Due to language
* limitations this will accept (though perhaps not do something
* meaningful) when array is a type that implements operator[].
*/
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
#else /* __cplusplus */
/* Evaluates to 0 if array is an array; compile error if not array
* (e.g. pointer). The built-in function used for type checking is
* not supported by GNU C++.
*/ */
#define IS_ARRAY(array) \ #define IS_ARRAY(array) \
ZERO_OR_COMPILE_ERROR( \ ZERO_OR_COMPILE_ERROR( \
!__builtin_types_compatible_p(__typeof__(array), \ !__builtin_types_compatible_p(__typeof__(array), \
__typeof__(&(array)[0]))) __typeof__(&(array)[0])))
#if defined(__cplusplus)
extern "C++" {
template < class T, size_t N >
#if __cplusplus >= 201103L
constexpr
#endif /* >= C++11 */
size_t ARRAY_SIZE(T(&)[N]) { return N; }
}
#else
/* Evaluates to number of elements in an array; compile error if not /* Evaluates to number of elements in an array; compile error if not
* an array (e.g. pointer) * an array (e.g. pointer)
*/ */
#define ARRAY_SIZE(array) \ #define ARRAY_SIZE(array) \
((long) (IS_ARRAY(array) + (sizeof(array) / sizeof((array)[0])))) ((long) (IS_ARRAY(array) + (sizeof(array) / sizeof((array)[0]))))
#endif
#endif /* __cplusplus */
/* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if /* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if
* "array" argument is not an array (e.g. "ptr" and "array" mixed up) * "array" argument is not an array (e.g. "ptr" and "array" mixed up)