arraysconstructorfortranfortran2008

What is the rank of a square bracket initialized array in Fortran 2008?


I want to understand if the following Fortran code complies with the Fortran 2008 standard.

module m
  implicit none

  type t
     integer, allocatable, dimension(:) :: r
  end type t

contains

  function tt(a,b)
    implicit none
    type(t), allocatable, dimension(:) :: tt
    type(t), intent(in), dimension(:) :: a,b
    allocate(tt, source = [a,b])     ! Is this square bracket correct ?
    return
  end function tt

  function ts(arg)
    implicit none
    type(t), allocatable, dimension(:) :: ts
    integer, intent(in) :: arg(:)
    allocate(ts(1))
    allocate(ts(1)%r, source = arg)
    return
  end function ts
end module m

program p
  use m
  implicit none
  type(t), dimension(2) :: c
  c=tt(ts([99,199,1999]),ts([42,142]))
  if (any (c(1)%r .ne. [99,199,1999])) STOP 1
  if (any (c(2)%r .ne. [42,142])) STOP 2
end program p

This above code works fine with gfortran-9.4.0 and generates the expected output. Since I am a beginner in Fortran, I got confused by a square bracket expression (marked in the code).

Inside the function tt, both a and b are t type arrays. In this example, both of them only have array size of 1.

What is [a,b]? I think it is an array initialized with square brackets, but each of its element is a t type array. (Not a t type scalar)

What is [a,b]'s rank? Does it match the return value tt which is also a t type allocatable array?

From Fortran 2008 standard

Each allocate-object shall be type compatible (4.3.1.3) with source-expr . If SOURCE= appears, source-expr shall be a scalar or have the same rank as each allocate-object.


Solution

  • The [a,b] here is an array constructor.1

    An array constructor creates a rank-1 array. This is the case:

    Coming to the specifics of the question:

    What is [a,b] ? I think it is a array initialized with square brackets, but each of its element is a t type array. (Not a t type scalar)

    An array constructor acts with sequences. If an array expression (including a whole array designator) appears inside the constructor, the constructor uses the elements of the array in element order. This means that

    allocate(tt, source = [a,b])
    

    is taken to be

    allocate(tt, source = [a(1), a(2), ..., b(1), b(2), ...])
    

    as a rank-1 array, not an array of arrays or a higher rank array.

    What is [a,b]'s rank ? Is it match the return value tt which is also a t type allocatable array ?

    As already noted, it's a rank-1 array, (with those values of a and b in element orders).

    The value of an expression for a source= specifier in the allocation is, as nearly everywhere else, independent of the use it's put to. That, is it must be compatible with the type of tt but it isn't constructed to be. The expression is created then, if necessary, converted to the type of tt.

    Consider the case with reals:

    double precision x(5)
    x = [1., 2., 3., 4., 5.2]
    end
    

    The array constructor is a real expression, not a double precision expression. Once constructed, it's converted to a double precision value for the assignment.

    Finally, note that constructed arrays are themselves never allocatable.


    1 Most often something which looks like [a,b] is an array constructor. However, for completeness, in some circumstances it can be a (coarray) image selector. There can never be ambiguity as to which case we have.