可分配的 Intent(inout) 参数可以是可选的吗?
Can An Allocatable Intent(inout) Argument Be Optional?
我在尝试定义一个子例程时遇到问题,该子例程的参数包含一个可分配的、可选的、如下所示的 intent(inout) 变量。代码编译正常,但出现 "Segmentation fault - invalid memory reference".
的运行时错误
子程序test_routine.f90
SUBROUTINE test_routine(A,B)
IMPLICIT NONE
REAL,ALLOCATABLE,INTENT(IN) :: A(:,:)
REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT) :: B(:,:)
B = A
B(:,:) = 1
END SUBROUTINE
该子程序打包在一个模块中,在Main中调用。
模块test_module.f90
MODULE test_module
IMPLICIT NONE
INTERFACE test_routine
MODULE PROCEDURE test_routine
END INTERFACE
END MODULE test_module
主要test_main.f90
PROGRAM main
USE test_module
IMPLICIT NONE
REAL,ALLOCATABLE :: A(:,:),B(:,:)
ALLOCATE(A(6,6))
ALLOCATE(B(6,6))
A(:,:) = 0
CALL test_routine(A,B) ! WORKS FINE
CALL test_routine(A) ! DOESN'T WORK!
END PROGRAM main
然后我尝试给另一个变量赋值op_B,来弥补B,如果主程序不传进去,B其实是不存在的,但是下面的代码还是不行.
SUBROUTINE test_routine(A,B)
IMPLICIT NONE
REAL,ALLOCATABLE,INTENT(IN) :: A(:,:)
REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT) :: B(:,:)
REAL,ALLOCATABLE :: op_B(:,:)
IF(.NOT. PRESENT(B)) THEN
ALLOCATE(op_B(SIZE(A,1),SIZE(A,2)))
B = op_B
END IF
B = A
B(:,:) = 1
END SUBROUTINE
顺便说一句,我也试过使用固定大小的数组,但仍然没有帮助。请问这样的事情是不是做不到?
伪参数可以是可选的、可分配的和 intent(inout)。
但是您不能定义或引用可选的虚拟参数,禁止将其传递给 PRESENT 或将其与另一个可选参数相关联。如果 'B' 不存在,则无法执行 'B = A'.
根据@lanH 的回答,我目前想到的唯一方法是为每个可选的虚拟参数指定一个别名。此版本现在可用。
SUBROUTINE test_routine(A,B)
IMPLICIT NONE
REAL,ALLOCATABLE,INTENT(IN) :: A(:,:)
REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT) :: B(:,:)
REAL,ALLOCATABLE :: op_B(:,:)
ALLOCATE(op_B(SIZE(A,1),SIZE(A,2)))
op_B = A
op_B(:,:) = 1
IF(PRESENT(B)) THEN
B = op_B
END IF
DEALLOCATE(op_B)
END SUBROUTINE
我在尝试定义一个子例程时遇到问题,该子例程的参数包含一个可分配的、可选的、如下所示的 intent(inout) 变量。代码编译正常,但出现 "Segmentation fault - invalid memory reference".
的运行时错误子程序test_routine.f90
SUBROUTINE test_routine(A,B)
IMPLICIT NONE
REAL,ALLOCATABLE,INTENT(IN) :: A(:,:)
REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT) :: B(:,:)
B = A
B(:,:) = 1
END SUBROUTINE
该子程序打包在一个模块中,在Main中调用。
模块test_module.f90
MODULE test_module
IMPLICIT NONE
INTERFACE test_routine
MODULE PROCEDURE test_routine
END INTERFACE
END MODULE test_module
主要test_main.f90
PROGRAM main
USE test_module
IMPLICIT NONE
REAL,ALLOCATABLE :: A(:,:),B(:,:)
ALLOCATE(A(6,6))
ALLOCATE(B(6,6))
A(:,:) = 0
CALL test_routine(A,B) ! WORKS FINE
CALL test_routine(A) ! DOESN'T WORK!
END PROGRAM main
然后我尝试给另一个变量赋值op_B,来弥补B,如果主程序不传进去,B其实是不存在的,但是下面的代码还是不行.
SUBROUTINE test_routine(A,B)
IMPLICIT NONE
REAL,ALLOCATABLE,INTENT(IN) :: A(:,:)
REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT) :: B(:,:)
REAL,ALLOCATABLE :: op_B(:,:)
IF(.NOT. PRESENT(B)) THEN
ALLOCATE(op_B(SIZE(A,1),SIZE(A,2)))
B = op_B
END IF
B = A
B(:,:) = 1
END SUBROUTINE
顺便说一句,我也试过使用固定大小的数组,但仍然没有帮助。请问这样的事情是不是做不到?
伪参数可以是可选的、可分配的和 intent(inout)。
但是您不能定义或引用可选的虚拟参数,禁止将其传递给 PRESENT 或将其与另一个可选参数相关联。如果 'B' 不存在,则无法执行 'B = A'.
根据@lanH 的回答,我目前想到的唯一方法是为每个可选的虚拟参数指定一个别名。此版本现在可用。
SUBROUTINE test_routine(A,B)
IMPLICIT NONE
REAL,ALLOCATABLE,INTENT(IN) :: A(:,:)
REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT) :: B(:,:)
REAL,ALLOCATABLE :: op_B(:,:)
ALLOCATE(op_B(SIZE(A,1),SIZE(A,2)))
op_B = A
op_B(:,:) = 1
IF(PRESENT(B)) THEN
B = op_B
END IF
DEALLOCATE(op_B)
END SUBROUTINE