Прочитать выделяемую строку со списком имен в Фортране
Начиная с Fortran 2003 можно работать с символьными строками переменной длины. Вместо того, чтобы работать архаично и объявлять постоянную длину строки, я хотел бы динамически читать строки символов моего списка имен.
Рассмотрим программу
program bug
implicit none
character(:), allocatable :: string
integer :: file_unit
namelist / list / string
open(newunit=file_unit,file='namelist.txt')
read(unit=file_unit,nml=list)
write(*,*) string
close(file_unit)
end program bug_namelist
и небольшой список имен, содержащийся в следующем файле namelist.txt:
&list
string = "abcdefghijkl"
/
Если я скомпилирую с GCC 8.2.0 с агрессивными флагами отладки, я получу
Warning: ‘.string’ may be used uninitialized in this function [-Wmaybe-uninitialized]
и на рунтине ничего не печатается, и это возникает:
Fortran runtime warning: Namelist object 'string' truncated on read.
и с компилятором Intel 17.0.6 с аналогичными флагами отладки, без флагов времени компиляции и следующей ошибки времени выполнения:
forrtl: severe (408): fort: (7): Attempt to use pointer STRING when it is not associated with a target
который указывает, что функция списка имен не может выделить строку переменной длины "сама по себе", потому что, если я добавлю строку
allocate(character(len=15) :: string)
ошибки исчезают. Это ожидаемое поведение? Или это дефект от компиляторов?
1 ответ
Это ожидаемое поведение, указанное стандартом Fortran. На самом деле, нигде в вводе-выводе Fortran не используются строки с отложенной длиной, которые обрабатываются так, как они находятся в присваивании. Предлагается рабочий элемент для следующего стандарта Фортрана ("F202X"), который позволит сделать это в ограниченном контексте (см. https://j3-fortran.org/doc/year/18/18-279r1.txt) Если я вспоминаю правильно, мы обсуждали добавление к списку и чтения NAMELIST к этому на более раннем собрании стандартов, но были подняты некоторые проблемы, которые я точно не помню, и мы вернемся к этому.