# Why the following implicit array assignment works?

**URL:** <https://fortran-lang.discourse.group/t/why-the-following-implicit-array-assignment-works/7523>\
**Category:** Help\
**Created:** [March 2, 2024, 7:44pm UTC](https://fortran-lang.discourse.group/t/why-the-following-implicit-array-assignment-works/7523 "2024-03-02T19:44:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![farragutman](https://avatars.discourse-cdn.com/v4/letter/f/f475e1/32.png) [@farragutman](https://fortran-lang.discourse.group/u/farragutman)\
**Post date:** [March 2, 2024, 7:44pm UTC](https://fortran-lang.discourse.group/t/why-the-following-implicit-array-assignment-works/7523/1 "2024-03-02T19:44:42Z")

</div>

Can anyone explain why the example below works?  
In the subroutine `subr`, variable `s` is scalar, and integer variables, `j` and `k` are not initialized, but somehow, the assignment to `s(i,k)` is applied to all possible values of `j` and `k` as if implied do exists, and the variable `s` is treated as if an array variable.  
This example can be compiled and run correctly with GNU Fortran compiler (gfortran), NVHPC Fortran compiler (nvfortran), and Intel Fortran compiler (ifort), but I don’t understand why this code works.  
(All tested compilers fail if the `PRINT` statement before the `s(i,k)` assignment statement is enabled, which may mean that the `s(i,k)` assignment statement works only if it is the first executable statement in the subroutine.)

```auto
      PROGRAM magicAssignment
      integer, parameter :: dp = selected_real_kind(15)
      integer, parameter :: mxpart = 14
      integer:: i,m 
      real(dp)::p_p(mxpart,4), val 
      val = 1._dp
      DO i=1, 4
      DO m=1, mxpart
        p_p(m,i) = val 
        val = val + 1._dp
      END DO
      END DO
      CALL subr(p_p)

      CONTAINS
      SUBROUTINE subr(p)
      implicit none
      real(dp),parameter:: two=2._dp
      integer:: j,k,error
      real(dp):: p(mxpart,4),s,sCal
! "Error: Unclassifiable statement" occurs for line 24 if the print
! statement below is enabled
! PRINT *,'start computation'
      s(j,k)=two*(p(j,4)*p(k,4)-p(j,1)*p(k,1)
     & -p(j,2)*p(k,2)-p(j,3)*p(k,3))
      error = 0 
      DO k=1, mxpart
      DO j=1, mxpart
      sCal=two*(p(j,4)*p(k,4)-p(j,1)*p(k,1)
     & -p(j,2)*p(k,2)-p(j,3)*p(k,3))
      IF ( s(j,k) .NE. sCal ) THEN
      PRINT *, 's(', j, ',', k, ') differs from the calculated value(',
     &sCal,')'
      error = error + 1 
      END IF
      END DO
      END DO
      IF ( error .EQ. 0 ) THEN
      PRINT *, '==> No error occurred!'
      END IF
      END SUBROUTINE subr    
      END PROGRAM magicAssignment    

```

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [March 2, 2024, 7:53pm UTC](https://fortran-lang.discourse.group/t/why-the-following-implicit-array-assignment-works/7523/2 "2024-03-02T19:53:01Z")

</div>

> [@farragutman](#):
>
> ```auto
> s(j,k)=two*(p(j,4)*p(k,4)-p(j,1)*p(k,1)
> & -p(j,2)*p(k,2)-p(j,3)*p(k,3))
> 
> ```

This is not an assignment but a [statement function](https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnb9/index.html).

Statement functions go into the _specification part_ of the subroutine. Executable statements like `print` go into the _executable part_ (the body of the procedure) which is below the specification part.

---

<div class="post-metadata">

**Author:** ![farragutman](https://avatars.discourse-cdn.com/v4/letter/f/f475e1/32.png) [@farragutman](https://fortran-lang.discourse.group/u/farragutman)\
**Post date:** [March 4, 2024, 1:03am UTC](https://fortran-lang.discourse.group/t/why-the-following-implicit-array-assignment-works/7523/3 "2024-03-04T01:03:26Z")

</div>

> [@ivanpribec](#):
>
> [statement function](https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnb9/index.html)

That solves my mystery.  
I’m new to Fortran and thus didn’t know about the statement function.  
Thanks a lot!

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [March 4, 2024, 3:02am UTC](https://fortran-lang.discourse.group/t/why-the-following-implicit-array-assignment-works/7523/4 "2024-03-04T03:02:02Z")

</div>

Normally, one would replace statement functions in a legacy code with a contained function in a modern fortran code. Unfortunately, that cannot be done in this particular case because the subroutine is already itself a contained procedure, and fortran allows only limited nesting levels. An alternative is to replace the statement function with a contained function at the same level as the subroutine. This case is simple enough to do that, but you would need to add the `p(:,:)` dummy argument array as an additional argument which is not in the original statement function, or reference the actual argument array` p_p(:,:)` directly from the main program.
