Array length can be calculated using *(&arr+1)-arr which then simplifies to (&arr)[1]-arr which further simplifies to 1[&arr]-arr.
But when the length is calculated in a function different from where memory allocation has been done, wrong results are computed.
For instance,
#include <iostream>
#define ARRAY_SIZE(arr) (1[&arr]-arr)
using namespace std;
void func(int *arr)
{
cout<<ARRAY_SIZE(arr)<<endl;
}
int main()
{
int arr[]={1,2,3,4,5};
cout<<ARRAY_SIZE(arr)<<endl;
func(arr);
}
This gives the output:
5
8
What accounts for such strange behaviour?
Array length can be calculated using *(&arr+1)-arr
Only if arr is actually an array. Within func, arr is a pointer, so this dereferences a random word of memory to give undefined behavoiur.
There is no way to tell the size of an array given just a pointer to its first element. You could pass the array by reference:
template <size_t N>
void func(int (&arr)[N]) {
cout<<ARRAY_SIZE(arr)<<endl;
cout<<N<<endl; // equivalent, and less weird
}
Using the same technique, we can reimplement ARRAY_SIZE without resorting to the preprocessor or any bizarre pointer arithmetic:
template <size_t N>
size_t ARRAY_SIZE(int (&arr)[N]) {
return N;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With