在Fortran中读取带有名称列表的可分配字符串

cir*_*ker 3 string fortran character allocatable-array

由于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
Run Code Online (Sandbox Code Playgroud)

以及namelist.txt文件中包含的小名单:

&list
string = "abcdefghijkl"
/
Run Code Online (Sandbox Code Playgroud)

如果我用GCC 8.2.0编译带有激进的调试标志,我得到

Warning: ‘.string’ may be used uninitialized in this function [-Wmaybe-uninitialized]
Run Code Online (Sandbox Code Playgroud)

在runtine,什么都没有打印出来,这就出现了:

Fortran runtime warning: Namelist object 'string' truncated on read.
Run Code Online (Sandbox Code Playgroud)

使用具有类似调试标志的英特尔编译器17.0.6,没有编译时标志和以下运行时错误:

forrtl: severe (408): fort: (7): Attempt to use pointer STRING when it is not associated with a target
Run Code Online (Sandbox Code Playgroud)

这表明namelist功能无法"自行"分配可变长度字符串,因为如果我添加该行

allocate(character(len=15) :: string)
Run Code Online (Sandbox Code Playgroud)

错误消失了.这是预期的行为吗?或者它是编译器的缺陷?

Ste*_*nel 6

这是Fortran标准规定的预期行为.实际上,Fortran I/O中没有任何地方延迟长度可分配字符串处理它们在内部赋值中的方式.有一个建议的工作项目用于下一个Fortran标准("F202X"),以便在有限的环境中实现这一点(参见https://j3-fortran.org/doc/year/18/18-279r1.txt)如果我记得正确地说,我们讨论过在早期的标准会议上添加列表导向和NAMELIST读取,但提出了一些我不记得的问题,我们将重新审视这一点.