Как известно, в GCC-7.1.0 появилась поддержка «user-defined io» стандарта Fortran 2003. На сайте Intel есть несколько примеров. С большинством из которых всё понятно и они даже собираются gfortran-7.3.0 и работают.
Проблема наблюдается с третьим примером:
! PROGRAM: udio_nml_read_write.f90
!
! This program tests NAMELIST READ and WRITE. In the WRITE subroutine, there
! are FORMATTED WRITES as well as NAMELIST WRITES.
!
MODULE UDIO
TYPE MYDT
INTEGER F1
INTEGER F2
CONTAINS
PROCEDURE :: MYSUBROUTINE
GENERIC :: READ (FORMATTED) => MYSUBROUTINE
END TYPE MYDT
INTERFACE WRITE (FORMATTED)
MODULE PROCEDURE :: WRITESUBROUTINE
END INTERFACE
CONTAINS
SUBROUTINE WRITESUBROUTINE (DTV, UNIT, IOTYPE, V_LIST, IOSTAT, IOMSG)
CLASS (MYDT), INTENT(IN) :: DTV
INTEGER*4, INTENT(IN) :: UNIT
CHARACTER (LEN=*), INTENT(IN) :: IOTYPE
INTEGER, INTENT(IN) :: V_LIST(:)
INTEGER*4, INTENT(OUT) :: IOSTAT
CHARACTER (LEN=*), INTENT(INOUT) :: IOMSG
INTEGER I, J
NAMELIST /SUBRT_NML/ I, J
I=DTV%F1
J=DTV%F2
WRITE (UNIT, '(A,2I5.2)', IOSTAT=IOSTAT) IOTYPE, DTV%F1, DTV%F2
WRITE (UNIT, NML=SUBRT_NML)
END SUBROUTINE WRITESUBROUTINE
SUBROUTINE MYSUBROUTINE (DTV, UNIT, IOTYPE, V_LIST, IOSTAT, IOMSG)
CLASS (MYDT), INTENT(INOUT) :: DTV
INTEGER*4, INTENT(IN) :: UNIT
CHARACTER (LEN=*), INTENT(IN) :: IOTYPE
INTEGER, INTENT(IN) :: V_LIST(:)
INTEGER*4, INTENT(OUT) :: IOSTAT
CHARACTER (LEN=*), INTENT(INOUT) :: IOMSG
! X and Y are aliases for DTV%F1 and DTV%F2 since field references
! cannot be referenced in a NAMELIST statement
INTEGER X, Y
NAMELIST /SUBRT_NML/ X, Y
READ (UNIT, *) DTV%F1, DTV%F2
X = DTV%F1
Y = DTV%F2
READ (UNIT, NML=SUBRT_NML, IOSTAT=IOSTAT)
END SUBROUTINE MYSUBROUTINE
END MODULE UDIO
PROGRAM UDIO_PROGRAM
USE UDIO
TYPE (MYDT) :: MYDTV
INTEGER :: A, B
NAMELIST /MAIN_NML/ A, MYDTV, B
OPEN (10, FILE='udio_nml_read_write.in')
READ (10, NML=MAIN_NML)
WRITE (6, NML=MAIN_NML)
CLOSE (10)
END PROGRAM UDIO_PROGRAM
На вход подаётся файл «'udio_nml_read_write.in»:
&MAIN_NML
A=100
MYDTV=20 30
&SUBRT_NML
X=20
Y=30
/
/B=200
/
На выходе должно быть:
&MAIN_NML
A = 100,
MYDTV=NAMELIST 20 30
&SUBRT_NML
I = 20,
J = 30
/
/B = 200
/
Но с gcc-7.3.0 на выходе получается
&MAIN_NML
A= 100,
MYDTV=NAMELIST 20 30&SUBRT_NML
I= 20,
J= 30,
/
B= 0,
/
, либо вместо «B = 0» может быть произвольное число, то есть словно «B» осталась неинициализированной.
Если во входном файле вместо строки " /B = 200" оставить только «B = 200» и добавить в конце пустую строку, то тогда в выводе будет «B = 200».
Но интересует первоначальный вариант входного файла (если он правильный, конечно).
Есть ли кто, из тех у кого есть intel fortran compiler (2016 и новее, кажется), проверить что выводит пример в результате отработки?
И главное, как этот пример вообще работает? Пока я это не очень понимаю. То есть, например, не совсем понятно как он считывает значения «20» и «30» второй раз и куда? И куда он считывает остальной текст или там во входных данных уже какой-то стандартный «текстовый шаблон» вбит и он его подставляет? Если что-то в «текстовых строках» поменять, то во время исполнения пример упадёт. А если поменять значения «X» и «Y», то они ни на что не влияют (на вывод, то есть словно они и не нужны).