C ++ value of getting array size

Here is a macro to get the size of the array

#define array_size(array) \ (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))) 

I think normal (sizeof (array) / (sizeof (array [0])) is good enough to get the size of the array.

I guess part

 (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*)) 

is to avoid anything that divides by zero, can anyone help explain?

Thanks in advance.

Greetings

+8
c ++ arrays
source share
3 answers

Multiplying sizeof array[0] in the divider by

 (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*)) 

makes the divisor zero if

 sizeof array == sizeof(void*) 

and

 sizeof array[0] > sizeof(void*) 

In these cases, you get division by zero during compilation, which will lead to compilation failure.

These checks are an attempt to detect arguments that are pointers (whether it is the result of converting from an array to a pointer or not), since you cannot know how large a pointer points to this array using this factor.

It fails if other types of pointers have different sizes than void* , and it does not detect pointers to things that are no larger than void* s. This probably does more harm than good, lulling the author into a false sense of security.

+12
source share

I think normal (sizeof (array) / (sizeof (array [0])) is good enough to get the size of the array.

Although this is not your main question, but you mentioned it. The correct way to determine the size of an array in C ++ uses patterns:

 template<typename T, size_t size> constexpr size_t array_size(T(&)[size]){ return size; } 
+6
source share

I assume this part is clear: sizeof( array ) / sizeof( array[0] )

This part (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*)) is a logical expression, so it returns true or false. When calculating the whole expression, therefore, multiplying sizeof( array[0] ) by the logical expression, the compiler converts the logical expression to 0 or 1. Thus, you get sizeof( array ) / (sizeof( array[0] ) * 1) or
sizeof( array ) / (sizeof( array[0] ) * 0) .

The first case is the normal and necessary case. The second case will give you a compiler error due to division by zero. Therefore, the code will not compile if you call, for example:

 long *p; // assuming a platform with sizeof(long)==sizeof(void*) array_size(p); 

But he will not catch errors, for example:

 char *p; array_size(p); 

And this does not compile for the case that I would like to compile for:

 long x[1]; // assuming a platform with sizeof(long)==sizeof(void*) array_size(x); 

BTW, if you declare this function as a macro (and in C ++ I really prefer a template style solution), you must change all array in the macro to (array) .

+1
source share

All Articles