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.
The
[a,b]here is an array constructor.1An array constructor creates a rank-1 array. This is the case:
(/ ... /)or[ ... ]Coming to the specifics of the question:
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
is taken to be
as a rank-1 array, not an array of arrays or a higher rank array.
As already noted, it's a rank-1 array, (with those values of
aandbin 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 ofttbut it isn't constructed to be. The expression is created then, if necessary, converted to the type oftt.Consider the case with reals:
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.