# Still trying to resolve this equivalence issue

I have tried using pointers, etc but I cannot shake this problem.

The one issue is that I cannot see how these two variables are being equated.

So, I have two parameters defined as…

integer, parameter   :: mj   = 4000
integer, parameter   :: me   = 9

Later, I have two arrays defined as…

double precision :: hydrogen(mj), element(mj, me)

equivalence (element, hydrogen)

So, I know that hydrogen is now an array with 4000 indices and element is an array with 4000 x 9 = 36000 elements.

I understand that the equivalence relates hydrogen(mj) to element(mj, 1); is that it?

When the system steps through the second dimension of element (me > 1), does this mean there is no equivalence there?

Basically, if I was to change the contents of element(200, 1) then the contents of hydrogen(200) would also alter. Yet, if I were to alter the contents of element(200, 2) or element(200,3) or element(200,4) this would have no impact upon hydrogen at all?

Am I correct there?

I hadn’t, actually, no.

It’s such an obvious to do, but if I might blame being focussed on too many things right now…?

Thank you. I’ll have a go once the current run of my code has finished.

Using EQUIVALENCE in new code is something to avoid. Modifying old code that contains EQUIVALENCE can be troublesome. In either case, one has to read the appropriate Fortran manuals/standards to understand the rules regarding this old feature, which was quite useful in the days when many large mainframe computers had as little as 32 kWords of memory, but is best avoided these days.

Here is a modified version of your example that illustrates how, in the presence of EQUIVALENCE, an error with regard to the upper bound of one array can cause changes to the other array in ways that may be unexpected and surprising.

program OverRun
implicit none
integer, parameter :: MH = 4, ME = 3
!
integer :: hyd(MH), elems(MH,ME)
equivalence (hyd,elems)         ! hyd overlays first column of elems
!
integer i,j,m,n
!
do i=1,MH
hyd(i) = i+1000
end do
do j=2,ME
do i=1,MH
elems(i,j) = i*1000+j*100
end do
end do
print '(i8,5x,3I8)',(hyd(i),elems(i,:),i=1,MH)
call update(hyd,7) ! 7 is in error; should have been just 4 or MH
print *
print '(i8,5x,3I8)',(hyd(i),elems(i,:),i=1,MH) ! Only first column of elems should have changed
end program

subroutine update(elem,n) ! triple values in elem
implicit none
integer i,n,elem(n)
elem = 3*elem
return
end subroutine

The program text may suggest that the call to UPDATE only changes the first column of ELEMS. However, because of passing the wrong value of n to the subroutine, the second column of ELEMS also gets changed, even though ELEMS itself was not passed to the subroutine as an argument.

2 Likes