I wonder how "%" works on array of derived type.
I wrote the following program where the "+" operator has been overloaded :
module my_mod
implicit none
type :: my_type
real :: r1 , r2
integer :: i1, i2
end type my_type
interface operator(+)
module procedure add_my_type_vec, add_my_type
end interface
contains
function add_my_type_vec(a,b) result(res)
type(my_type), dimension(:),intent(in) :: a, b
type(my_type), dimension(size(a)) :: res
res%r1 = a%r1 + b%r1
res%r2 = a%r2 + b%r2
res%i1 = a%i1 + b%i1
res%i2 = a%i2 + b%i2
end function add_my_type_vec
function add_my_type(a,b) result(res)
type(my_type), intent(in) :: a, b
type(my_type) :: res
res%r1 = a%r1 + b%r1
res%r2 = a%r2 + b%r2
res%i1 = a%i1 + b%i1
res%i2 = a%i2 + b%i2
end function add_my_type
end module my_mod
program my_pgm
use my_mod
implicit none
type(my_type),allocatable, dimension(:) :: my_vec1, my_vec2, my_vec3
write(*,*) "Sum on type : ", my_type(1.0, 2.0, 1, 2) + my_type(1.0, 2.0, 1, 2)
allocate(my_vec1(1000), my_vec2(1000), my_vec3(1000))
my_vec1 = my_type(1.0, 2.0, 1, 2)
my_vec2 = my_type(1.0, 2.0, 1, 2)
my_vec3 = my_vec1 + my_vec2
write(*,*) "Sum on vec of type : ", my_vec3(123)
end program my_pgm
In the add_my_type_vec
function, how does %
work? For example, in the instruction res%r1 = a%r1 + b%r1
, is there the creation (i.e. memory copy) of two arrays of real that contain only a%r1
and b%r1
, the sum is done on these arrays, and after the assignment is done on res%r1
? I guess it's more complicated.
Compilers are generally free to create array temporaries whenever they'd like.1 There are times, such as you'll see in may posts here where temporary copies are effectively required or are highly desirable. This other answer, for example, takes some cases.
As a practical example, this is a case where thinking can be elaborated, rather than a strict answer given.
In the whole code here, there are many opportunities for an array temporary to be created around add_my_type_vec
, such as:
a
and b
could be copieda%r1
, b%r1
, etc.) could each be copieda%r1+b%r1
, etc.) could go in to a temporary locationNot one copy of any class is required here, or is particularly beneficial.
The dummy arguments a
and b
are assumed shape, and the compiler knows that they are (simply) contiguous.
The array a%r1
(etc.) is not contiguous, but is of constant stride: a compiler can easily handle striding through the elements.
The left-hand side of res%r1 = a%r1 + b%r1
does not appear in any way (especially not a complicated way) on the right-hand side: evaluation of the right-hand side does not affect the left-hand side so no copy is required to hold the evaluation before assignment.
Equally, with the assignment of the function result, there's no interactions between any of the variables involved.
There's no need to work around the demands of finalization anywhere.
Essentially, all the compiler has to do is iterate over the elements of my_vec3
and directly assign the pair-wise sum of elements of my_vec1
and my_vec2
, striding through those arrays in pretty boring ways.
A compiler could decide to do any of the copies if it thought wise, or if it wanted to play extra safe. Usually, you can ask a compiler to tell you (compile- or run-time) when it's making a copy or is putting the machinery in place to enable a copying decision.
The only reason to be worried about the components (use of %
) is that the referenced arrays are not contiguous. Fortran is very well able to cope with non-contiguous arrays without requiring copies. Restrictions on "complicated" arrays and "complicated" uses of components are there to make handling these common cases truly very boring (for compiler writers).
1 A compiler is required to ensure that effects on a temporary are effects on an entity associated with that temporary. For example, if there's a temporary copy of a dummy argument then the actual argument must reflect any (appropriate) changes. Fortran's rules on aliasing are restrictions on programs which make the compiler's life much easier in determining when effects are required to be visible in techniques such as copy-in/copy-out.