Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29279 讨论

Calling type bound procedures on derived type components trashes data

MDK
初学者
533 次查看
[plain]module data_type

    implicit none
    type :: data_t
        integer :: val = -1
    contains
        procedure :: set
    end type

contains

    subroutine set(this, val)
        implicit none
        class(data_t), intent(out) :: this
        integer, intent(in) :: val
        this%val = val
    end subroutine

end module


module container_type

    use data_type
    
    implicit none
    
    type :: container_t
        type(data_t) :: data1
        type(data_t) :: data2
    contains
        procedure :: set_good 
        procedure :: set_clobber
        procedure :: print => print_container
    end type
        
contains

    subroutine set_clobber(this, val)
        implicit none
        class(container_t), intent(out) :: this
        integer, intent(in) :: val
        call this%data1%set(val)  ! TBP call: bad!
        call this%data2%set(2*val)
    end subroutine    

    subroutine set_good(this, val)
        implicit none
        class(container_t), intent(out) :: this
        integer, intent(in) :: val
        call set(this%data1, val)  ! regular call: ok
        call set(this%data2, 2*val)
    end subroutine    

    subroutine print_container(this)
        implicit none
        class(container_t), intent(in) :: this
        write (*, *) this%data1%val, this%data2%val        
    end subroutine

end module


program ifort_bug

    use container_type
    
    implicit none
    type(container_t) :: x
    
    call x%set_good(-3)
    call x%print()

    call x%set_clobber(10)  ! data2 gets written to data1
    call x%print()
        
    read (*, *)  ! pause        

end program[/plain]


This might be related to a previous bug (<>), but this doesn't involve procedure pointers. This is with 11.1.054, which I just downloaded today.

If you have one derived type that contains derived type components, calling type-bound procedures on the components will clobber the values of other components. In the example above, attempting to set the value of 'data2' using a TBP will change the value of 'data1' instead. The workaround is to use regular calls--'set(data2, val)' instead of 'set(data1, val)'--but this gets increasingly undesirable as you start working with multiple derived types across several modules.
0 项奖励
5 回复数
Steven_L_Intel1
533 次查看
Thanks - we'll look into this.
0 项奖励
Steven_L_Intel1
533 次查看
I believe this is a different problem, the issue ID is DPD200148795. What appears to be happening is that in set_clobber, the compiler is passing set_clobber's THIS as the THIS argument to set rather than the individual data1 and data2 components. Thanks for letting us know of the problem.
0 项奖励
abhimodak
新分销商 I
533 次查看
May be this is related to what Steve said but just an FYI:

I find that when stepping through the debugger the values shown for the components are messed up. This is true even when the results are not "messed up". On the other hand, printing the values in the set* subroutines do show them correctly.

Abhi
0 项奖励
Lorri_M_Intel
员工
533 次查看
Quoting - abhimodak
May be this is related to what Steve said but just an FYI:

I find that when stepping through the debugger the values shown for the components are messed up. This is true even when the results are not "messed up". On the other hand, printing the values in the set* subroutines do show them correctly.

Abhi

Dummy arguments that are CLASSes do not display correctly in the debugger. We know (really!) and are working on fixing that.

Sorry for the inconvenience --

- Lorri
0 项奖励
Steven_L_Intel1
533 次查看
The problem reported in this thread (wrong results) is expected to be fixed in Update 5, due late this month (or maybe early Feb.)
0 项奖励
回复