Strange result with polymorphic variables

Janus Weil janus@gcc.gnu.org
Mon Aug 29 12:47:00 GMT 2011


Hi,

> the reduced program below (I removed the scaling and the 3D version)
> seems to work properly
> with the exception of the need for deallocating the result variable in
> add_vector_2d.

Right. With "-fcheck=all" I get:

At line 56 of file random_walk_2.f90
Fortran runtime error: Attempting to allocate already allocated
variable 'add_vector_2d'

This is certainly a bug (and also the reason for the earlier
segfault). I have the strong suspicion that we just forget to nullify
allocatable CLASS results values on entry.

The funny thing is: If I remove the loop in your main program and just
execute it once, everything works! Puzzling ....

Cheers,
Janus




> ----------
> ! random_walk.f90 --
> !     Simulate a random walk in two and three dimensions
> !
> module points2d3d
>
>    implicit none
>
>    type point2d
>        real :: x, y
>    contains
>        procedure               :: print           => print_2d
>        procedure               :: random_vector   => random_vector_2d
>        procedure               :: add_vector      => add_vector_2d
>        procedure               :: assign          => assign_2d
>        generic                 :: operator(+)     => add_vector
>        generic                 :: assignment(=)   => assign
>    end type point2d
>
> contains
>
> subroutine assign_2d( point1, point2 )
>    class(point2d), intent(inout) :: point1
>    class(point2d), intent(in)    :: point2
>
>    point1%x = point2%x
>    point1%y = point2%y
>
> end subroutine assign_2d
>
> subroutine print_2d( point )
>    class(point2d) :: point
>
>    write(*,'(2f10.4)') point%x, point%y
> end subroutine print_2d
>
> subroutine random_vector_2d( point )
>    class(point2d) :: point
>
>    call random_number( point%x )
>    call random_number( point%y )
>
>    point%x = 2.0 * (point%x - 0.5)
>    point%y = 2.0 * (point%y - 0.5)
>
> end subroutine random_vector_2d
>
> function add_vector_2d( point, vector )
>    class(point2d), intent(in)  :: point, vector
>    class(point2d), allocatable :: add_vector_2d
>
>    ! Workaround for gfortran 4.6
> !    if ( allocated( add_vector_2d ) ) then
> !        deallocate( add_vector_2d )
> !    endif
>
>    allocate( add_vector_2d )
>    add_vector_2d%x = point%x + vector%x
>    add_vector_2d%y = point%y + vector%y
>
> end function add_vector_2d
>
> end module points2d3d
>
> program random_walk
>
>    use points2d3d   ! Both 2D and 3D points available
>
>    type(point2d), target   :: point_2d
>    type(point2d), target   :: vector_2d
>
>    class(point2d), pointer :: point
>    class(point2d), pointer :: vector
>
>    integer        :: nsteps = 10
>    integer        :: i
>    integer        :: trial
>    real           :: deltt  = 0.1
>
>    point  => point_2d
>    vector => vector_2d
>    write(*,*) 'Two-dimensional walk:'
>
>    call point%random_vector
>
>     do i = 1,nsteps
>        call vector%random_vector
>
>        point = point + vector
>
>        call point%print
>    enddo
> end program random_walk
>



More information about the Fortran mailing list