Declare automatic arrays using shape of argument, without using size intrinsic

I wish automatic arrays whose shapes are the same as that of a procedure argument could be declared more concisely. If x is a 3-D procedure argument you can write

real :: y(size(x,1), size(x, 2), size(x, 3))

but it is verbose, and it’s possible to slip and unintentionally write

real :: y(size(x,1), size(x, 2), size(x, 2))

More concise and less error-prone would be

real :: y(shape(x))

This would be allowed if the rank of x is known at compile time, as it usually is. Another possible syntax is

real, mold(x) :: y

I know you can make y a local allocatable array and write

allocate (y, mold=x)

A similar thread was How to concisely declare a function result as a multi-dimensional automatic array?

4 Likes

This is in fact valid now (I believe).

8.5.8.2 Explicit-shape array

C833 An explicit-bounds-expr shall be a restricted expression that is a rank one integer array with constant size.

It comes in with handful of the “rank-agnostic” syntax in F2023

2 Likes

I should really read the F2023 draft when I get the chance. This is the second time in a week I am caught off guard about a new feature of Fortran, the first one was split.

I gave a brief overview recently.

While this is now valid, I’m still hesitant to recommend its use in declaring dummy arguments. Nothing verifies that the actual argument is the same shape. It can lead to weird bugs for multi-dimensional arrays, or flat out memory corruption in any case.

4 Likes

And what if one wants to specify lower bounds ? is real :: y(lbound(x):shape(x)) possible ?

real :: y(lbound(x):)

is valid for assumed shape, and if you do still want to go the explicit shape route, one would do

real :: y(lbound(x):ubound(x))