j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
178 stars 15 forks source link

Assignments in PURE subprograms with a dummy argument of a POINTER attribute #190

Open FortranFan opened 3 years ago

FortranFan commented 3 years ago

The issue mentioned by @klausler in #189 can do with a separate discussion thread on its own:

If you're looking for weirdness with assignments in pure subprograms, try this one: it's not valid to store through a pointer dummy argument to a pure subprogram, even when the pointer has been allocated in the subprogram.

Two rather similar external subprograms are subsequently provided, one identified as "subroutine bad" and the other, "subroutine good".

Has there been a formal interp response by the Fortran committee on this, or a discussion at the J3/WG5 mailing list?

FortranFan commented 3 years ago

@FortranFan wrote Dec. 23, 2020 9:40 PM EST:

.. Has there been a formal interp response by the Fortran committee on this, or a discussion at the J3/WG5 mailing list?

My reason for this question is the issue mentioned by @klausler , "it's not valid to store through a pointer dummy argument to a pure subprogram, even when the pointer has been allocated in the subprogram." and especially in the context of the 2 provided examples appears inaccurate vis-à-vis current Fortran standard.

Something is amiss, this can do with additional discussion in this thread so as not to distract from the topic in #189.

FortranFan commented 3 years ago

Consider the case of "bad" in the 2 examples mentioned in #189 ,

subroutine bad(p)
  real, pointer :: p
  allocate(p)
  p = 3.14159
end subroutine

@klausler mentioned in the context of f18,

It's unclear to me how these points are related to the subroutine bad in those 2 examples.

Consider below a calling program with that subroutine - note marked as PURE to make it relevant: is there a Fortran processor that in any way supports the point, "it's not valid to store through a pointer dummy argument to a pure subprogram, even when the pointer has been allocated in the subprogram." I fail to see it with gfortran and Intel Fortran, these 2 compilers process it as I expect per Fortran standard.

pure subroutine bad(p)
  real, pointer :: p
  allocate(p)
  p = 3.14159
end subroutine
program test
   interface
      pure subroutine bad(p)
        real, pointer :: p
      end subroutine
   end interface
   real, pointer :: x
   integer :: istat
   character(len=256) :: imsg
   call bad( x )
   if ( associated(x) ) then
      print *, "x = ", x, "; expected is 3.14159"
      deallocate(x, stat=istat, errmsg=imsg)
      if ( istat /= 0 ) then
         print *, "deallocation of x failed: ", new_line(""), imsg
         stop
      end if
      x => null()
   else
      print *, "x is unexpectedly disassociated"
   end if
end program

Processor outputs:

C:\Temp>ifort /standard-semantics /warn:all /stand:f18 bad.f90 Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1 Build 20201112_000000 Copyright (C) 1985-2020 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 14.26.28806.0 Copyright (C) Microsoft Corporation. All rights reserved.

-out:bad.exe -subsystem:console bad.obj

C:\Temp>bad.exe x = 3.141590 ; expected is 3.14159

C:\Temp>gfortran -Wall -std=f2018 bad.f90 -o gcc-bad.exe

C:\Temp>gcc-bad.exe x = 3.14159012 ; expected is 3.14159

C:\Temp>

FortranFan commented 3 years ago

And re: "(IMO the rule about pointer dummy arguments should not apply when they have INTENT(OUT).)""

sblionel commented 3 years ago

There is no such rule. Perhaps @klausler is misreading the restrictions related to pure functions. C1594 lists the restrictions on what a pure procedure can do with dummy arguments, and it says "shall not be used ... (3) as the data-target in a pointer-assignment-stmt,", but this constraint limits "a pointer dummy argument of a pure function" and so does not apply to a pointer dummy of a pure subroutine. I don't spot any more general restrictions on a pointer dummy of a pure subroutine.

Interp F18/010 relates to pure procedure pointers, but that's a different thing.