Question: Why is this an error:

```
typedef int H[4];

H * h = new H;        // error: cannot convert 'int*' to 'int (*)[4]' in initialization

```

?

Furthermore, why is this *not* an error:

```
H * h = new H[1];

```

?

Why does the compiler consider that `new H` returns an `int *`, whereas `new H[1]` returns an `H *` as expected ?

To put it another way: **why is it that `T * t = new T;` is correct for a general type T, but is not correct when `T` is an array type ?**

What would be the canonical way to allocate a simple array type such as this via `new` ?

Note that this is a simplified example, so e.g. `new int[4]` is not an acceptable workaround - I need to use the actual type from the preceding `typedef`.

Note also that I'm aware that using `std::vector`, `std::array`, *et al* is generally preferable over C-style arrays, but I have a "real world" use case where I need to work with types such as the above.

Answer: 
In the C++ standard `new` and `new[]` are specifically separated because they can be be different allocators for performance and efficiency reasons; allocating an array vs. a single object has different usage patterns that allocator implementations optimise for.

The syntax is probably different because the compile-time type introspection techniques available when it was standardised wasn't nearly as reliable as it is today.

To make sensible code, the preferred way IMO would be:

```
struct H { int values[4]; }

H * h = new H;

```

That way, your `H` type logically "contains" your array of four `int` values - but the in-memory structure should still be compatible (`assert(sizeof(H) == 4 * sizeof(int))`); and you get to use object-style allocation of your fixed-size arrays. More... C++-ey.
You can see why if you basically do the typedef substitution manually:

```
H * h = new H;

```

Reduces to:

```
int[4]* h = new int[4];

```

while

```
H * h = new H[1];

```

reduces to:

```
(int*)[4] h = new int[1][4];

```

Because of the array to pointer decay rules, this is legal.

If you want an actual workaround, and you know the type of H, you can do something like:

```
typedef int* J;
typedef int H[4];

J j = new H; // This will work

```