[J3] Multifaceted question on OPTIONAL assumed rank dummy arguments

Clune, Thomas L. (GSFC-6101) thomas.l.clune at nasa.gov
Tue Feb 8 21:33:12 UTC 2022


There is an unfortunate pattern in some of the code that I work with where there are large number of 2D/3D optional arguments.   When they are present _and_ associated then a corresponding diagnostic is computed.  Otherwise the diagnostic is skipped.   This resulted in (incorrect) code of the form:

IF (PRESENT(X_1) .and. ASSOCIATED(X_1)) THEN
   <compute diagnostic for x_1
END IF
IF (PRESENT(X_2) .and. ASSOCIATED(X_2)) THEN
   <compute diagnostic for x_2
END IF
IF (PRESENT(X_3) .and. ASSOCIATED(X_3)) THEN
…

People in my group wanted to fix the assumption about short circuiting and tried to introduce a couple of logical functions:

LOGICAL FUNCTION CHECK_2D(x)
   REAL, OPTIONAL, POINTER :: x(:,:)

   CHECK_2D=.FALSE. !unless
   IF (PRESENT(X)) THEN
      IF(ASSOCIATED(X)) CHECK_2D=.TRUE.
   END IF
END FUNCTION

And similarly for 3D.   But then discovered they could not overload a single interface because the arguments are optional.   Being the clever sort, I suggested exploiting the new fangled assumed rank capability:

   LOGICAL FUNCTION check(arr)
      REAL, OPTIONAL, POINTER :: arr(..)

      check = .FALSE. ! unless

      IF (PRESENT(arr)) THEN
         IF (ASSOCIATED(arr)) check = .TRUE.
         END IF
      END IF

   END FUNCTION

Now this compiles with the 3 compilers I tried and the following give the expected results:


   real, pointer :: x2(:,:) => null()
   real, pointer :: x3(:,:,:) => null()

   print*,'2D null:  ', check(x2)
   print*,'3D null:  ', check(x3)
   print*,'absent:   ', check()

   allocate(x2(4,5))
   allocate(x3(3,4,5))

   print*,'2D alloc:  ', check(x2)
   print*,'3D alloc:  ', check(x3)

However, when I tried to make a more realistic example all compilers crashed saying that there was an illegal reference to the optional argument:

   subroutine driver_2d(msg, x)
      character(*), intent(in) :: msg
      real, intent(in), optional, pointer :: x(:,:)

      print*,msg, check(x)

   end subroutine driver_2d
…

   call driver_2d('present: ',x2)
   call driver_2d('missing: ')  ! crashes with message about referencing optional argument

The consistency of the failure makes me think I’ve misunderstood something about the standard, but the error message is perplexing.  A non-present dummy should be perfectly fine for passing to an optional dummy argument in CHECK().     If anything I was expecting an error that we cannot use PRESENT or ASSOCIATED except within a SELECT RANK construct (which would defeat the design anyway.)

Is this just a consistent bug?   Or …

Thanks,


  *   Tom

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20220208/1c674d1a/attachment-0001.htm>


More information about the J3 mailing list