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]
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.
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)
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.
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.