So let us say I have an array:
int a[3] = { 1, 2, 3 };
Now if I were to check the type of ‘a’, on my machine I get:
cout<<typeid(a).name(); // prints 'A3_i'
Now if I take the address of ‘a’, then dereference that address, the type does not change (which I really like, because in my mind ‘taking the address’ and ‘dereferencing’ are inverse operations):
cout<<typeid(*&a).name(); // also prints 'A3_i'
However if I dereference ‘a’ first, then take the address of that, the type does change (which I admit I have a hard time not liking, because when I dereferenced the array I should get an int, and when I take the address of that int, I should get a pointer-to-int, and it turns out I do):
cout<<typeid(&*a).name(); // prints 'Pi'
So here are my two questions:
1) Once an array-type has decayed into a pointer-type, is there anyway to get it back to an array-type?
I tried the obvious strategy of casting-like-you-just-don’t-care:
cout<<typeid( (int[3]) &*a).name(); // does not compile
// "error: ISO C++ forbids casting to an array type `int [3]'"
Is there another cast that would work? Or it is this type of conversion strictly off-limits?
2) Whether or not you can ever get back to the array-type, exactly what information is sliced and lost in the decay-to-pointer proccess?
I understand that a pointer-type and an array-type are not equivalent. I assume that the array-type is a strict superset of the information stored in the pointer-type. Does this sound right?
I have read in other questions that the extra information in the array-type is: knowledge of whether or not the array is on the stack, and also its size (it must know the size of the array somehow, because it is part of the type, right?). Is there any other information hidden in the array-type?
I’m not sure if this is quite what you’re looking for, but you can use typecasting to get back an object with the same type as the original array. The idea is to use the little-known types pointer-to-array and reference-to-array to recover the information. For example:
The idea is that we typecast the reference created by using
*&arr[0]to typechar (&)[137], a reference to an array of 137 characters. Now that the reference has this type, thesizeofoperator knows that it should print 137, since the size of an array of 137 characters is indeed 137.However, this only works if you typecast to the correct type! For example, this is perfectly legal:
So you can recover the information, but you can easily get that information wrong and lead to a case where you’ve recovered the incorrect information.
Again, I’m not sure if this is what you were looking for, but it shows that you can indeed use casting to get back the array size information.