A questão é exatamente o título: Fortran permite alterar membros de dados de tipo derivado SUBROUTINE
mesmo com INTENT(IN)
, como proteger dados? Sou bem novo em Fortran e esse comportamento de permitir a mutação de membros de dados de um tipo derivado apesar do INTENT(IN)
atributo no argumento fictício de tipo derivado é bem preocupante para mim. Existe uma maneira de capturar esse tipo de mutação insegura com o compilador? Por exemplo, gfortran -Wall
não parece fazer isso, mas talvez esse seja um problema comum o suficiente em bases de código legadas ou mesmo modernas para onde alguma detecção estática do problema esteja disponível de alguma forma?
Programa de exemplo:
! @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
Saída:
1
2
3
4
5
-1
2
3
4
5