AP_Common: give some type safety to ARRAY_SIZE macro

Now that most places in the code use the ARRAY_SIZE macro instead of
coding it by hand, let's use some type safety in its definition. This is
a C++ version of similar macros used in kmod, Linux kernel and the
source of them, ccan.

A C++ version like this is used in V8 (the JS engine) and other open
source projects.

The main benefit of this version is that you get a compile error if you
pass in a variable that's not an array. For example,

     Bla y[10];
     Bla *y_ptr = y;

     void foo(Bla x[])
     {
         // build error since x[] decay to a pointer in function
         // parameter
         for (int i = 0; i < ARRAY_SIZE(x); i++) {
             ...
         }

         // build error since y_ptr is not an array
	 for (int i = 0; i < ARRAY_SIZE(y_ptr); i++) {
             ...
	 }
     }

I added the additional specialization to allow arrays of size 0.
This commit is contained in:
Lucas De Marchi 2015-09-24 14:56:19 -03:00 committed by Andrew Tridgell
parent 617626f9f5
commit 7ba6f92eb5
1 changed files with 7 additions and 1 deletions

View File

@ -80,7 +80,13 @@
#define LOWBYTE(i) ((uint8_t)(i)) #define LOWBYTE(i) ((uint8_t)(i))
#define HIGHBYTE(i) ((uint8_t)(((uint16_t)(i))>>8)) #define HIGHBYTE(i) ((uint8_t)(((uint16_t)(i))>>8))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) template <typename T, size_t N>
char (&_ARRAY_SIZE_HELPER(T (&_arr)[N]))[N];
template <typename T>
char (&_ARRAY_SIZE_HELPER(T (&_arr)[0]))[0];
#define ARRAY_SIZE(_arr) sizeof(_ARRAY_SIZE_HELPER(_arr))
// @} // @}