您可以在 Fortran 中测试空指针吗?
Can you test for nullpointers in Fortran?
我正在尝试使用 gfortran
学习 Fortran2018。
在玩弄指针时,我注意到似乎没有用于测试空指针的工具。所以我有两个问题:
- 在 Fortran 中是否真的没有(直接的)方法来测试指针是空指针还是“准备好使用”?
- 如果没有,为什么到目前为止在 Fortran 中不认为它是必要的?
更实际地说,在下面的代码片段中:我们如何在执行期间的任何时候发现分配给 p
是否“安全”? (可能想象一个更复杂的 allocate
、nullify
和 deallocate
语句序列。)
program test
implicit none
real, pointer :: p
! p = 333.333 ! Segfault, p is neither defined, nor allocated
! Since p is not defined, checking whether it's
! associated to a target gives arbitrary results:
print *, "Start: Pointer p associated? ", associated(p) ! Result: True or False
nullify(p) ! Now p is defined, but `null`
print *, "Nullyfied: Pointer p associated? ", associated(p) ! False
! p = 123.456 ! Still a segfault
allocate(p) ! Now p can be accessed
print *, "Allocated: Pointer p associated? ", associated(p) ! True
p = 987.654 ! Now assignment is possible
allocate(p) ! Loses the value pointed to by p.
print *, p ! Result: 0.00000000
deallocate(p) ! Now accessing p generates a segfault again.
print *, "Deallocated: Pointer p associated? ", associated(p) ! False
! Never allowed:
! allocated(p)
! p == null()
! p .eqv. null()
end program test
一个使用 associated()
函数测试空指针。 returns 关联指针为真,空指针为假。
对于未定义的指针,结果是“未定义的行为”(可以得到任何东西)。
一般来说,没有安全的方法来判断一个指针是否“准备好使用”,就像没有安全的方法来判断一个变量是否是 currently defined.
只有当指针处于已定义的关联状态时才可以使用ASSOCIATED
内部函数,但没有可比较的方法来确定(在 Fortran 程序本身内)指针是否处于已定义的关联状态。
如果指针是已定义的关联状态,ASSOCIATED
会告诉你指针是否指向某物(甚至在某些情况下甚至可以使用它是否指向)并且可以使用。
但是,如果指针不是已定义的指针关联,则试图查询其关联状态是违反Fortran 标准的(这比未定义的结果更强,这意味着您的整个程序都被破坏了)。
您可以通过采取合理的步骤来确保指针关联状态不会变成或开始为未定义来帮助自己,但作为程序员,了解关联状态是否已定义完全是您的责任。
一种提供帮助的方法是设置指针的初始关联状态:
real, pointer :: p => NULL() ! Defined association status, not-associated
real, pointer :: q ! Undefined association status
print *, ASSOCIATED(p) ! Allowed
print *, ASSOCIATED(q) ! Not allowed
end
(我不会说 ASSOCIATED(p)
告诉我们 .FALSE.
,因为 ASSOCIATED(q)
意味着我们没有有效的程序。)
总而言之,如果您细心,可以使用 ASSOCIATED
可靠地判断指针是否关联,但您必须小心。
我正在尝试使用 gfortran
学习 Fortran2018。
在玩弄指针时,我注意到似乎没有用于测试空指针的工具。所以我有两个问题:
- 在 Fortran 中是否真的没有(直接的)方法来测试指针是空指针还是“准备好使用”?
- 如果没有,为什么到目前为止在 Fortran 中不认为它是必要的?
更实际地说,在下面的代码片段中:我们如何在执行期间的任何时候发现分配给 p
是否“安全”? (可能想象一个更复杂的 allocate
、nullify
和 deallocate
语句序列。)
program test
implicit none
real, pointer :: p
! p = 333.333 ! Segfault, p is neither defined, nor allocated
! Since p is not defined, checking whether it's
! associated to a target gives arbitrary results:
print *, "Start: Pointer p associated? ", associated(p) ! Result: True or False
nullify(p) ! Now p is defined, but `null`
print *, "Nullyfied: Pointer p associated? ", associated(p) ! False
! p = 123.456 ! Still a segfault
allocate(p) ! Now p can be accessed
print *, "Allocated: Pointer p associated? ", associated(p) ! True
p = 987.654 ! Now assignment is possible
allocate(p) ! Loses the value pointed to by p.
print *, p ! Result: 0.00000000
deallocate(p) ! Now accessing p generates a segfault again.
print *, "Deallocated: Pointer p associated? ", associated(p) ! False
! Never allowed:
! allocated(p)
! p == null()
! p .eqv. null()
end program test
一个使用 associated()
函数测试空指针。 returns 关联指针为真,空指针为假。
对于未定义的指针,结果是“未定义的行为”(可以得到任何东西)。
一般来说,没有安全的方法来判断一个指针是否“准备好使用”,就像没有安全的方法来判断一个变量是否是 currently defined.
只有当指针处于已定义的关联状态时才可以使用ASSOCIATED
内部函数,但没有可比较的方法来确定(在 Fortran 程序本身内)指针是否处于已定义的关联状态。
如果指针是已定义的关联状态,ASSOCIATED
会告诉你指针是否指向某物(甚至在某些情况下甚至可以使用它是否指向
但是,如果指针不是已定义的指针关联,则试图查询其关联状态是违反Fortran 标准的(这比未定义的结果更强,这意味着您的整个程序都被破坏了)。
您可以通过采取合理的步骤来确保指针关联状态不会变成或开始为未定义来帮助自己,但作为程序员,了解关联状态是否已定义完全是您的责任。
一种提供帮助的方法是设置指针的初始关联状态:
real, pointer :: p => NULL() ! Defined association status, not-associated
real, pointer :: q ! Undefined association status
print *, ASSOCIATED(p) ! Allowed
print *, ASSOCIATED(q) ! Not allowed
end
(我不会说 ASSOCIATED(p)
告诉我们 .FALSE.
,因为 ASSOCIATED(q)
意味着我们没有有效的程序。)
总而言之,如果您细心,可以使用 ASSOCIATED
可靠地判断指针是否关联,但您必须小心。