Others have said that the code is non-standard, but they
haven't completely said why. In the subroutine "b" and
"a" are completely aliased--thay are the same actual
argument. This is OK so far. But there is the general
rule that when two (or more) dummy arguments refer
to the same actual argument, then neither one of them
can be changed while the subroutine is executing. The
rule is even more general, anything known by two or more
names, for instance if the actual argument is a module or
common variable, then it can't be changed by either
name. (EQUIVALENCE doesn't count as two names). You
can't get around this rule by using intent(in) or any
other tricks.
The rational for the rule is to allow the compiler to
do copy-in/copy-out as an argument passing scheme and,
probably more important, to allow the optimizer to
keep variables in registers.
Dick Hendrickson
-------------- Original message ----------------------
From: S Yuan <[log in to unmask]>
> Hi,
>
> For the following code, some complilers write out 1.0 and some write out
> 0.0 for op(1:3,1:3,1). Which one is correct, or standard conforming?
>
> First time to post a question. Thanks.
>
> S Yuan
>
> program main
> implicit none
> real :: op(3,4,2), s
>
> op=0.0
> s=1.0
>
> call adds(op(1:3,1:3,1),op(1:3,1:3,1),s)
> write(*,"(3(3f8.4,/))")op(1:3,1:3,1)
>
> stop
> contains
>
> subroutine adds(b,a,s)
> real, intent(in out) :: b(3,3),a(3,3),s
> real :: c(3,3)
> c=a+s
> b=c
> ! write(*,"(3(3f8.4,/))")b
> return
> end subroutine adds
>
> end program main
|