Meaning of the intent for pointer dummy arguments

Dear all,

I thought, that the intent attribute for a pointer only restricts, whether the association status of the pointer can be changed within the procedure. However, two compilers (Intel, GNU) refuse to compile the code below, while NAG is fine with it. Can any of the standard experts say, whether the code is complying?

module test
  implicit none

contains

  subroutine change_pointer_target(ptr)
    ! NOTE: the pointer association is not changed, only its target
    real, pointer, intent(in) :: ptr(:)

    call random_number(ptr)
    ptr(:) = ptr + 1.0

  end subroutine change_pointer_target

end module test

[EDIT: I’ve stripped away some superfluous parts of the demonstration code]

2 Likes

Is it not an issue of changing the rank?

No, the failing compilers already fail to compile the module itself, before even looking at the program part. I have removed now the program part, which was superfluous for the demonstration…

Well, it always helps to test that a compiler has not merely read and nodded at the source but has actually understood the meaning and will perform the expected calculations.

The one, which compiles the code, executes it also correctly as far as I can tell. The question is, however, whether it is that one compiler which is standard complying, or the two others, which refuse compilation. I intuitively would think, that the code is complying with the standard, so compilers should access, but maybe someone knows (or can find it much faster), which part of the standard covers this.

(J3/18-007r1) 8.5.10 (2) “INTENT attribute”

The INTENT (IN) attribute for a pointer dummy argument specifies that during the invocation and execution of the procedure its association shall not be changed except that it may become undefined if the target is deallocated other than through the pointer (19.5.2.5).

As far as I can see, only the target is referenced in the two executable statements.

I reckon it’s a compiler bug and if interested, OP can file support requests with the compiler implementors.

It appears the two compilers in question have somehow “special-cased” the intrinsic RANDOM_NUMBER and go beyond what the standard states regarding it:

module m
contains
   subroutine s1(a)
      real, pointer, intent(in) :: a
      !call s2(a)           !<-- Ok with Intel and gfortran 
      call random_number(a) !<-- but not this
   end subroutine 
   subroutine s2(x)
      real, intent(out) :: x
      x = 0.0
   end subroutine 
end module 

C:\Temp>gfortran -c a.f90
a.f90:10:23:

10 | call random_number(ptr)
| 1
Error: ‘harvest’ argument of ‘random_number’ intrinsic at (1) cannot be INTENT(IN)

1 Like

It might also be useful to see if the Intel Classic is doing the same as the LLVM-based version, but I am not in a position to try this, this evening.

Thanks a lot for all the comments. @kargl If that’s the checked in fix for GNU Fortran, thousand thanks for this very quick fix! @FortranFan I’ve now reported it to Intel, I just wanted to be sure, that it is indeed a bug. Actually, I reported a slightly modified version of your example, as that shows it even cleaner than my original one. @NormanKirkby Yes, the classic compiler (also) fails to compile it.

1 Like

No problem, I’ve posted it now, thanks.

FWIW, your module compiles fine with the Cray compiler. INTENT specified for a pointer argument does, as you suspected, apply to the pointer association status of the argument and has no effect on the target. There is a proposal for a future revision to add a new INTENT-like attribute that would apply to the target, but it turns out to be non-trivial.

This is not a simple issue. fpt has, internally, the intents:

Label argument
Function argument
Subroutine argument
Data in
Data inout
Data out
Attributes in
Attributes inout
Attributes out

If you are tracking units and dimensions across a code you need this complexity. I think that there should be a way for the language to express this.

John

1 Like