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.
CodePudding user response:
The [a,b]
here is an array constructor.1
An array constructor creates a rank-1 array. This is the case:
- in every revision of the Fortran standard (F90 )
- whether the array constructor uses
(/ ... /)
or[ ... ]
- whatever the use of the array constructor as an expression
- whatever the type of the constructed array and its sequence values
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 at
type array. (Not at
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 valuett
which is also at
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.
CodePudding user response:
In Fortran 2008, array constructors are defined in the 4.8 chapter of the standard.
The very first sentence in point 1 says
An array constructor constructs a rank-one array value from a sequence of ...
Hence, all arrays constructed using the array constructor are of rank 1. Higher ranks can be created from them using reshape()
.