On Thursday, February 20, 2020 at 6:51:40 PM UTC-5, Martin Keiter wrote:
> .. I ran into a a bug in my program, which I could trace down to
> the copy subroutine not working for an array, but only for individual
> copies. ..
>
> which outputs (with ifort 19 and gfortran)
> ..
To OP and other interested readers using Intel Fortran and/or gfortran,
You may know another thread recently on this forum touched upon the same topic involving type-bound procedure for a defined assignment and the ELEMENTAL attribute:
https://groups.google.com/d/msg/comp.lang.fortran/q6CPgOdmlss/OJFwkUNbGAAJ
And as I stated therein, there are a couple of scenarios where one or both the compilers of Intel Fortran and gfortran show unexpected behavior relative to the Fortran standard, at least per my read of it.
1) A derived type containing a component which is a derived type extended from another type that has the defined assignment.
--- begin case 1 ---
module b_m
type :: b_t
integer :: i = 0
logical :: defined_assignment = .false.
contains
procedure, pass(lhs) :: assign_b_t
generic :: assignment(=) => assign_b_t
end type
contains
elemental subroutine assign_b_t( lhs, rhs )
! Argument list
class(b_t), intent(inout) :: lhs
class(b_t), intent(in) :: rhs
lhs%i = rhs%i
lhs%defined_assignment = .true.
end subroutine
end module
program case1
use b_m, only : b_t
type, extends(b_t) :: e_t
end type
type :: f_t
type(e_t) :: e
end type
type(f_t) :: foo(2), bar(2)
bar = foo
print *, "bar(1)%e%defined_assignment = ", bar(1)%e%defined_assignment, "; expected value is T."
if ( .not. bar(1)%e%defined_assignment ) error stop "Program did not work as expected."
stop "SUCCESS"
end program case1
--- begin case 1 ---
Upon execution of program compiled using gfortran, the run-time behavior is:
bar(1)%e%defined_assignment = F ; expected value is T.
ERROR STOP Program did not work as expected.
Error termination. Backtrace:
Could not print backtrace: libbacktrace could not find executable to open
#0 0xffffffff
#1 0xffffffff
#2 0xffffffff
#3 0xffffffff
#4 0xffffffff
#5 0xffffffff
#6 0xffffffff
#7 0xffffffff
#8 0xffffffff
#9 0xffffffff
And similar output is generated using Intel Fortran as well.
2) But now, Intel Fortran has an issue processing an even simpler scenario involving a derived type containing a component which is a derived type with a defined assignment:
--- begin case 2 ---
module b_m
type :: b_t
integer :: i = 0
logical :: defined_assignment = .false.
contains
procedure, pass(lhs) :: assign_b_t
generic :: assignment(=) => assign_b_t
end type
contains
elemental subroutine assign_b_t( lhs, rhs )
! Argument list
class(b_t), intent(inout) :: lhs
class(b_t), intent(in) :: rhs
lhs%i = rhs%i
lhs%defined_assignment = .true.
end subroutine
end module
program case2
use b_m, only : b_t
type :: c_t
type(b_t) :: b
end type
type(c_t) :: foo(2), bar(2)
bar = foo
print *, "bar(1)%b%defined_assignment = ", bar(1)%b%defined_assignment, "; expected value is T."
if ( .not. bar(1)%b%defined_assignment ) error stop "Program did not work as expected."
stop "SUCCESS"
end program case2
--- end case 2 ---
gfortran works as I expect in this case but with Intel Fortran the program output unexpectedly is as follows:
bar(1)%b%defined_assignment = F ; expected value is T.
Program did not work as expected.