Beginner question on coarrays

In the book Modern Fortran by Milan Curcic, "7.4.2 Allocating dynamic coarrays"

I see that for allocatable coarrays, the definition is

real, dimension(:), codimension[:], allocatable :: a

and not

real, dimension(:), codimension[*], allocatable :: a

Why is that?

Fortran tries to adhere to a pattern, when it comes to using * and :

: generally means that the variable in question may have different values for the corresponding attribute during execution of the code where it is in scope. The whole idea of ALLOCATABLE is indeed that, in that scope, its co-extents could be one value in some statement, and a different in another statement. Other examples: assumed-shape arrays REAL, INTENT(IN) :: X(:,:), deferred-shape arrays POINTER, REAL :: Y(:).

* generally means that the value of that attribute is not known at compile-time but will remain fixed during the scope that name comes into existence for. Other examples: assumed-size arrays REAL :: A(LDA,*), implied-shape constant arrays PARAMETER, INTEGER :: I(*)=[1,2,3]

For the CODIMENSION, since the number of images is fixed at the beginning of execution and will never change, the * is the appropriate symbol.

According to your insights, where I agree, here is what my gcc disitribution reports when I change : with *.

weather_stats_parallel.f90:13:24:

13 |   real, allocatable :: gather(:)[*]
|                        1~~~~~~~~~~~
Error: Allocatable coarray variable 'gather' at (1) must have deferred shape
make: *** [makefile:22: weather_stats_parallel] Error 1

this is unexpected for me.

PS: I use gcc-16.2.0-64 from equation.com.

At declaration, you must use (:)[:]. Or CODIMENSION[:], DIMENSION(:) and nothing but the name at the end.

Can you show us the ALLOCATE statement?

The book gets it right

allocate(gather(grid_size)[*])

and the declaration is as I described

real(real32), allocatable :: gather(:)[:] 

the error happens when I take the “initiative” to change it as

real(real32), allocatable :: gather(:)[*] 

in the source code. I get why I caused the error, I do not get why the definition of the book/standard is not making sense. Because for a scalar is like that

integer :: a[*] 

It is unintuitive to me.

Well, the syntax in the scalar nonallocatable case declaration a[*] looks exactly like the syntax in the ALLOCATE, [*]. ALLOCATABLE variables need : at declaration and must use * (as the last one) at allocation time. Non-allocatables must use * at declaration.

Thank you. It makes sense now. When in Fortran do as Fortran heads do!

I suppose Fortran could allow an ALLOCATE( x(N,*) ) to mean grab as many columns as possible, but it currently does not. It would be rather cool…