Reputation: 105
I'm wondering why new doesn't seem to retain the array information and just returns an int*:
#include <iostream>
using namespace std;
typedef int (*p_to_array)[80];
typedef int arr[80];
int main()
{
arr a;
p_to_array p = &a; //fine
p_to_array p2 = new arr; // incompatible types
return 0;
}
Upvotes: 7
Views: 642
Reputation: 60979
You can either use the array syntax or a typedef-name to allocate arrays with new
- both is allowed and equivalent according to [expr.new]/5:
When the allocated object is an array (that is, the noptr-new-declarator syntax is used or the new-type-id or type-id denotes an array type), the new-expression yields a pointer to the initial element (if any) of the array.
As you can see, for arrays, solely a pointer to the initial element is given; Not a pointer to the array object itself. Thus the type yielded is int*
, not int (*)[N]
.
The reason why a pointer to the initial element is returned is quite simple: It is the pointer that you want to work with.
We want to write
auto p = new int[50];
// Or
int* p = new int[50];
So as to be able to use normal subscripting:
p[49] = 0xDEADBEEF;
That would be nonsensical with p
if it was of type int(*)[50]
pointing to the array object, because the subscript would add 49*50*4 to the address, not just 49*4 - because of subscript semantics and pointer arithmetics.
We would have to either use two subscripts:
p[0][49] = ...;
Which is horrific and unnecessarily redundant. Or we could use a cast:
int* p = static_cast<int*>(new int[50]); // Or with auto
But that is ugly too.
To avoid such hassles, this rule was introduced.
Upvotes: 4
Reputation: 39370
I might be totally wrong about this: (i.e. this is little more than an educated guess)
new arr;
is equivalent to:
new int[80];
which by language rules returns int*
.
From cppreference.com: (thanks to @interjay for pointing out I actually cited the irrelevant part)
The new-expression returns a prvalue pointer to the constructed object or, if an array of objects was constructed, a pointer to the initial element of the array.
My understanding of that is that when allocating an array, the new[]
form will be picked. The only thing your example changes is the syntax; it doesn't make the language treat arrays as non-arrays (regular objects).
Upvotes: 6
Reputation: 310980
In this declaration
p_to_array p2 = new arr; // incompatible types
type of initializer new arr;
does not correspond to the type of variable p2
The type of initializer is int *
that is the initializer is pointer to the initial element of the allocated array. The type of variable p2
is int (*p_to_array)[80]
according to the typedef definition.
There is no implicit conversion from type int *
to type int (*p_to_array)[80]
. So the compiler issues an error.
The correct declaration could look for example the following way
p_to_array p2 = new arr[1];
Upvotes: 1