Is passing a null pointer to a function and a subroutine valid according to the Fortran 2003 standard? Please suppose that the called function and the subroutine can correctly handle the case in which the dummy argument is a null pointer. I am especially interested in the case where such function and subroutine are a 'member' function and subroutine of a derived type.
I would like to avoid checking the association status of each pointer in the calling side if it is allowed by standard, in much the same way that I don't have to treat the zero-size array separately. At the same time, I do not want to rely on a behavior not specified by the standard.
As far as I tried with the following example, ifort
and gfortran
showed
different behaviors regarding this point.
moo.f90
MODULE moo
IMPLICIT NONE
PRIVATE
PUBLIC LL
TYPE LL
INTEGER :: i0
CONTAINS
PROCEDURE :: func1
PROCEDURE :: func2
END type LL
CONTAINS
FUNCTION func1(self) RESULT(pLL_dest)
TYPE(LL), POINTER :: pLL_dest
CLASS(LL), TARGET, INTENT(IN) :: self
write(*,*) 'hello from func1'
pLL_dest => null()
!pLL_dest => self
END FUNCTION func1
FUNCTION func2(self) RESULT(flg)
LOGICAL :: flg
CLASS(LL), TARGET, INTENT(IN) :: self
write(*,*) 'hello from func2'
flg = .true.
END FUNCTION func2
END MODULE moo
main.f90
PROGRAM chk_nullpo
USE moo, ONLY : LL
IMPLICIT NONE
!CLASS(LL), POINTER :: pLL_s=>null()
TYPE(LL), POINTER :: pLL_s=>null()
TYPE(LL), POINTER :: pLL_d=>null()
LOGICAL :: flg
write(*,*) 'associated(pLL_s) =',associated(pLL_s)
write(*,*) 'associated(pLL_d) =',associated(pLL_d)
write(*,*) 'func1..'
pLL_d => pLL_s%func1()
write(*,*) 'associated(pLL_s) =',associated(pLL_s)
write(*,*) 'associated(pLL_d) =',associated(pLL_d)
write(*,*) 'func2..'
flg =pLL_s%func2()
write(*,*) 'flg=', flg
write(*,*) 'associated(pLL_s) =',associated(pLL_s)
write(*,*) 'associated(pLL_d) =',associated(pLL_d)
write(*,*) 'normal end'
END PROGRAM chk_nullpo
Executable generated by ifort
caused a run-time error when the member
subroutine func2
is called with the null pointer.
$ ifort -v
ifort version 14.0.2
$ ifort -c moo.f90 -stand f03 -warn all -check
$ ifort -c main.f90 -stand f03 -warn all -check
$ ifort -o ex_ifort moo.o main.o -stand f03 -warn all -check
ifort: warning #10182: disabling optimization; runtime debug checks enabled
$ ./ex_ifort
associated(pLL_s) = F
associated(pLL_d) = F
func1..
hello from func1
associated(pLL_s) = F
associated(pLL_d) = F
func2..
forrtl: severe (408): fort: (7): Attempt to use pointer PLL_S when it is not associated with a target
Image PC Routine Line Source
ex_ifort 0000000000402AE1 Unknown Unknown Unknown
ex_ifort 0000000000402336 Unknown Unknown Unknown
libc.so.6 00002AC53B23DF45 Unknown Unknown Unknown
ex_ifort 0000000000402229 Unknown Unknown Unknown
$
On the other hand, executable generated by gfortran
finished without error.
$ gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING
$ gfortran -c moo.f90 -std=f2003 -Wall -fbounds-check
moo.f90:26.21:
FUNCTION func2(self) RESULT(flg)
1
Warning: Unused dummy argument 'self' at (1)
moo.f90:16.21:
FUNCTION func1(self) RESULT(pLL_dest)
1
Warning: Unused dummy argument 'self' at (1)
$ gfortran -c main.f90 -std=f2003 -Wall -fbounds-check
$ gfortran -o ex_gfortran moo.o main.o -std=f2003 -Wall -fbounds-check
$ ./ex_gfortran
associated(pLL_s) = F
associated(pLL_d) = F
func1..
hello from func1
associated(pLL_s) = F
associated(pLL_d) = F
func2..
hello from func2
flg= T
associated(pLL_s) = F
associated(pLL_d) = F
normal end
$
Is the behavior of ifort
not comforming the standard, or
is the behavior of gfortran
just graceful? Or, the standard doesn't
say anything about this point?
I note that both of these compilers are older versions, and I guess a newer version might show different behavior.