我正在尝试循环传递给Fortran程序的所有参数,参数的数量各不相同。因此,我使字符串数组可分配。
但是,一旦我开始所述循环,如果给出任何参数,我就会得到一个段错误。
拥有可分配的字符串数组有什么问题吗?
法典:
program read_args
implicit none
character(len=999), allocatable :: args(:)
integer, allocatable :: i, nargs
nargs=command_argument_count()
if ( nargs == 0 ) then
print*, 'err: no arguments or options'
stop
end if
allocate(args(1:nargs))
print*, nargs, size(args(:))
do i=1,nargs
call getarg(i,args(i))
args(i)=trim(adjustl(args(i)))
end do
end program
打印参数的数量和数组大小,一旦我尝试读取参数,就会出现段错误。
编译器,gfortran - gcc , v8.3.0
debian 10
(为了避免XY问题:这个想法是检查参数列表中的选项标志以及获取所有应该处理的文件名(
结果:
$ ./a.out
err: no arguments or options
$ ./a.out arg1 arg2
2 2
<Segfault>
正如注释所述,该程序中的问题是在 do 构造中使用未分配变量i
,而不是在构造中使用字符数组。
我们可以准确地说明为什么这种i
的使用是有问题的。
在
do i=1,nargs
我们有i
是"do变量"(Fortran 2018,11.1.7.2(。 在这样的 do 构造中,我们知道(Fortran 2018,11.1.7.4.1(作为循环处理的一部分:
DO 变量变为使用初始参数的值定义
那么,这个"定义"是否首先涉及i
的分配?
它没有。 这与作为内在赋值一部分的显式分配过程形成鲜明对比,例如(例如有效nargs=command_argument_count()
(。 不允许在未分配i
的情况下使用此"定义"(Fortran 2018,5.4.10(:
不得引用或定义未分配的可分配变量。
i
的定义与使用初始参数i
内部赋值的目标的过程不同。
通常,具有可分配的标量(如i
和nargs
(可能很有用,但在此问题的情况下,情况并非如此:从中删除allocatable
属性不会更改逻辑。 或者,可以在输入 do 构造之前显式分配i
(无需为其提供值(。