问题正是标题:Fortran 允许在SUBROUTINE
即使有的情况下更改派生类型数据成员INTENT(IN)
,如何保护数据?我对 Fortran 还很陌生,尽管INTENT(IN)
派生类型伪参数具有属性,但这种允许改变派生类型数据成员的行为让我非常担心。有没有办法用编译器捕获这些不安全的突变?例如,gfortran -Wall
似乎没有这样做,但也许这是遗留甚至现代代码库中一个相当常见的问题,以至于可以通过某种方式对问题进行某种静态检测?
示例程序:
! @file main.f90
!
! @purpose: Show data members of derived types are mutable in SUBROUTINE
!
! @compile: gfortran -Wall main.f90
PROGRAM test
IMPLICIT NONE
INTEGER :: n_states = 1
INTEGER :: len_state = 5
INTEGER :: i, j
TYPE t_states
INTEGER, POINTER, CONTIGUOUS :: state(:) ! (len_state,)
END TYPE t_states
TYPE(t_states), ALLOCATABLE :: states(:) ! (n_states,)
ALLOCATE(states(1:n_states))
! Populate allocated array of states
DO i = 1, n_states
ALLOCATE(states(i)%state(len_state))
DO j = 1, len_state
states(i)%state(j) = j
PRINT *, states(i)%state(j)
END DO
PRINT *
END DO
CALL unsafe_mutation(states(1))
! Print state array after modification
DO j = 1, len_state
PRINT *, states(1)%state(j)
END DO
CONTAINS
! Arbitrary update of state data member even though INTENT(IN)!!!
SUBROUTINE unsafe_mutation(p_states)
TYPE(t_states), INTENT(in) :: p_states
p_states%state(1) = -1
END SUBROUTINE
END PROGRAM test
输出:
1
2
3
4
5
-1
2
3
4
5