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