除此之外,如果问题是“是否
A(0)
正在访问不应访问的某个内存区域”,我认为很有可能是这样。虽然结果取决于编译器(并且无法证明任何事情),但我们可以使用
c_loc
查看一些信息,例如,
program test
use iso_c_binding, only: c_loc
implicit none
integer, target :: i
integer, allocatable, target :: X(:), A(:), B(:)
allocate( X( 1 ), A( 0 ), B( 1 ) )
print *, "X:"
do i = 0, 2
print *, i, c_loc( X( i ) ), X( i )
enddo
print *, "A:"
do i = 0, 2
print *, i, c_loc( A( i ) ), A( i )
enddo
print *, "B:"
do i = 0, 2
print *, i, c_loc( B( i ) ), B( i )
enddo
end
然后,gfortran-7.2(没有选项)会给出以下结果:
X:
0 140362656006716 0
1 140362656006720 0 <-- (*1)
2 140362656006724 -1879048192
A:
0 140362656006732 -1879048192
1 140362656006736 0
2 140362656006740 -1879048192
B:
0 140362656006748 -1879048192
1 140362656006752 0 <-- (*2)
2 140362656006756 -1879048192
Oracle Studio Fortran 12.5(无选项)提供了
X:
0 20258316 0
1 20258320 0 <-- (*1)
2 20258324 0
A:
0 20258348 0
1 20258352 0
2 20258356 0
B:
0 20258380 0
1 20258384 0 <-- (*2)
2 20258388 0
在编程中,我们能够访问的有效内存区域仅限于 (*1) 和 (*2)。由于数组元素在内存中是连续访问的,因此除了 (*1) 和 (*2) 之外的内存位置可能代表其他数据/元数据/缓冲区等,如果我们无意中修改这些值,可能会发生任何事情(包括第三次世界大战或最近的巨额数字货币盗窃)。众所周知,通常可以使用诸如 gfortran-7 -fcheck=all
的选项进行检查。
X:
At line 11 of file test.f90
Fortran runtime error: Index '0' of dimension 1 of array 'x' below lower bound of 1
或者 f95 -C test.f90
(适用于Oracle)
X:
****** FORTRAN RUN-TIME SYSTEM ******
Subscript out of range. Location: line 11 column 31 of 'test.f90'
Subscript number 1 has value 0 in array 'X'
我们对于
A(0)
也会得到类似的错误,因此无法访问
A(0)
(因为
A
是一个空数组)。(唯一的例外是当通过参数或存储关联等方式访问
A
时,但我想这是另一回事...)