Fortran Pointer as argument in a subroutine

the program is quite simple :

!
subroutine print_array(a)
integer, dimension(*) :: a
print*,'print::loc(a)=',loc(a)
end subroutine  print_array
!
program test
integer, target, dimension(10) :: ival
integer, pointer, dimension(:)  :: ival_ptr
!
print*,'test::loc(ival)=',loc(ival)
!
ival_ptr=>ival
call print_array(ival_ptr)
!
end

Version 1 - Contiguous memory -

gfortran -fcheck=array-temps -Warray-temporaries main.F

main.F:12.23:
call print_array(ival_ptr)
1
Warning: Creating array temporary at (1)

And during execution, I can see that there is no copy:

./a.out
test::loc(ival)= 140731006653952
print::loc(a)= 140731006653952


Version 2 - Non contiguous memory -

Just replace
call print_array(ival_ptr)
by:
call print_array(ival_ptr(1:10:2))

gfortran -fcheck=array-temps -Warray-temporaries main.F
main.F:13.23:
call print_array(ival_ptr(1:10:2))
1
Warning: Creating array temporary at (1)

and a warning during execution:

./a.out
test::loc(ival)= 140733975879936
At line 13 of file main.F
Fortran runtime warning: An array temporary was created
print::loc(a)= 25096048


Analysis:

  • version 1 :
    • print_array receive the array ‘a’ as contiguous memory block
    • we see that both arraies have the same adress : loc(a) = loc(ival)
    • no runtime warning
  • version 2 :
    • print-array receive a temporary array
    • loc(a) != loc(ival)
    • runtime warning

Questions :

  • Version 2 I get the expected result, a warning during compilation and another at runtime
  • Version 1 : I don’t understand the warning during compilation ?, is there a risk to pass a pointer as argument to a subroutine ?

What do you think ?

Thanks.

1 Like

In program 1, a run-time check is needed to see if a copy needs to be made, because a pointer can be discontiguous. gfortran evidently gives the compile time warning for this possibility, though perhaps the wording could be improved. Since you asked for warnings for temps, it’s fine that it did so in this case.

Intel Fortran doesn’t offer this compile-time warning (in any situation). It is fine to pass a pointer to a non-pointer dummy argument.

A side note: LOC() is an extension, but convenient to use in this test.

1 Like

Thank you Steve.
So I will use pointers safely :slight_smile:

In the code you showed, it would be simpler to pass ival than ival_ptr. In your actual code, are you sure you need to pass a pointer?

the code here is just a mockup to illustrate the issue. In the real code, I really need a fortran pointer because the memory is allocated in C. The link between c pointers and fortran pointers is done using C_F_POINTER !

Subroutine this(variableA)
implicit none
! You are missing this next line !
integer, dimension(*), intent(inout) :: variableA 
print *, "This; ", variableA(1), "!"
end subroutine this

Have fun!

knarfnarF