I can not get this code working, but I fail to understand what I'm doing wrong:
module m_test type t1 integer :: a contains procedure, private :: r_t1 generic :: read(formatted) => r_t1 end type type, extends(t1) :: t2 integer :: b end type contains subroutine r_t1(dtv, unit, iotype, vlist, iostat, iomsg) class(t1), intent(inout) :: dtv integer, intent(in) :: unit character(len=*), intent(in) :: iotype integer, intent(in) :: vlist(:) integer, intent(out) :: iostat character(len=*), intent(inout) :: iomsg integer i,j select type (dtv) type is (t2) read(unit, fmt="(2i4)", iostat=iostat, iomsg=iomsg) dtv%a , dtv%b print *, "a:",dtv%a, ", b:", dtv%b class default read(unit, fmt="(i4)", iostat=iostat, iomsg=iomsg) dtv%a print *, "a:",dtv%a end select end subroutine end module program test use m_test character(len=:), allocatable :: str type(t1) :: x type(t2) :: z str="123456789" read(str, fmt="(DT)") x print *, x%a read(str, fmt="(DT)") z print *, "z" print *, z%a print *, z%b end program
It compiles ok, but produces a run-time error:
C:\TEMP>ifort test.f90 /standard-semantics Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 18.104.22.168 Build 20150407 Copyright (C) 1985-2015 Intel Corporation. All rights reserved. Microsoft (R) Incremental Linker Version 11.00.61030.0 Copyright (C) Microsoft Corporation. All rights reserved. -out:test.exe -subsystem:console test.obj C:\TEMP>test a: 1234 1234 a: 1234 , b: 5678 forrtl: severe (24): end-of-file during read, unit -5, file Internal Formatted Read Image PC Routine Line Source test.exe 00007FF789348099 Unknown Unknown Unknown test.exe 00007FF789333FDB Unknown Unknown Unknown test.exe 00007FF78933139F Unknown Unknown Unknown test.exe 00007FF78939D5EE Unknown Unknown Unknown test.exe 00007FF789386864 Unknown Unknown Unknown KERNEL32.DLL 00007FF9814816AD Unknown Unknown Unknown ntdll.dll 00007FF982BC34A5 Unknown Unknown Unknown C:\TEMP>
I'm probably trying to do something that is not allowed, but fail to see my error. Any enlightenment is appreciated
I think your code is correct. What I see happening is that your UDIO routine is called for Z and then the run-time library tries to read component a separately, which it shouldn't. I will send this on to the developers. Issue ID is DPD200375355.
Thank you Steve,
it is a small consolation that my code is correct. I stumbled upon this problem while trying to create a reproducer for another problem, where the additional component of the second type that extends t1 is read correctly inside the UDTIO procedure, but in the calling program the component has a completely different and wrong content.
Does the problem also occur with the upcoming version 16?
Well, I managed to reduce my original problem code.
instead of the format for reading z:
read(str, fmt="(DT)") z
i put (erroneously) an "a" too much:
read(str, fmt="(DT,a)") z
then the program does not crash, but the value for the component b is completely off:
C:\TEMP>test a: 1234 1234 a: 1234 , b: 5678 z 1234 538976313 C:\TEMP>
Now I hope I can find a workaround to this problem, otherwise lots of code rewriting will have to be done.
I admit that I am puzzled by the behavior, as we have had this feature for a while and this is not an unusual operation. I will wait to see what the developers say. You would not want to add an A format item (nor anything else, really)
I am now told that the fix for this will be in Update 3. The fix is in the run-time library - if you linked to the DLL libraries, which is the default, your program should pick it up automatically, though a recompile is never a bad idea.