I was recently reading about difference between T*
and T[size]
, T being the type, and it make me curious so I was playing around with it.
int main()
{
int a[10];
using int10arrayPtr_t = int(*)[10];
int10arrayPtr_t acopy = a;
}
In the above code, int10array_t acopy = a;
is an error with message
error C2440: 'initializing':
cannot convert from 'int [10]' to 'int10array_t'
And this compiles:
int main()
{
int a[10];
using int10arrayPtr_t = int*;
int10arrayPtr_t acopy = a;
}
Isnt the type int(*)[10]
closer the the type of int a[10];
than int*
? So why does it not allow the first case?
CodePudding user response:
You need to take the address explicitly, e.g.
int10arrayPtr_t acopy = &a; // acopy is a pointer to array containing 10 ints
// ^
The 2nd case works because array could decay to pointer, for a
, it could convert to int*
implicitly, and acopy
is a pointer to int
(note that it's not a pointer to array).
CodePudding user response:
Array designators used in expressions with rare exceptions are implicitly converted to pointers to their first elements.
So if you have for example an array
T a[N];
then you may write
T *p = a;
because due to the implicit conversion the above declaration is equivalent to
T *p = &a[0];
If you apply the address of operator & to an array then you get a pointer dereferencing which you will get the original object.
For example
T a[N];
T ( *p )[N] = &a;
std::cout << sizeof( *p ) << '\n';
the output statement will give the size of the array a.
Here is a demonstration program.
#include <iostream>
#include <iomanip>
#include <type_traits>
int main()
{
const size_t N = 10;
using T = int;
T a[N];
T *p = a;
std::cout << "std::is_same_v<T &, decltype( *p )> is "
<< std::boolalpha << std::is_same_v<T &, decltype( *p )>
<< '\n';
std::cout << "sizeof( *p ) = " << sizeof( *p ) << '\n';
T( *q )[N] = &a;
std::cout << "std::is_same_v<T ( & )[N], decltype( *q )> is "
<< std::boolalpha << std::is_same_v<T ( & )[N], decltype( *q )>
<< '\n';
std::cout << "sizeof( *q ) = " << sizeof( *q ) << '\n';
}
The program output is
std::is_same_v<T &, decltype( *p )> is true
sizeof( *p ) = 4
std::is_same_v<T ( & )[N], decltype( *q )> is true
sizeof( *q ) = 40
CodePudding user response:
In your first example, the symbol int10arrayPtr_t
is an alias for a "pointer to an array of 10
integers". In your second example the same symbol is an alias for "pointer to a single integer". That's quite a different thing.
Also, it's true that arrays decays to pointers to their first element, but it's a pointer to a single element of the array. I.e. plain a
will decay to &a[0]
, which have the type int*
. To get a pointer to the array you need to use the pointer-to operator &
for the whole array, as in &a
.