我在其他人的代码中遇到了一些似乎应该是fortran规范中未定义的行为的代码。有一个数组定义了明确的上限和下限
ALLOCATE(arraysmall(10,5:10))
这个数组被传递到一个子程序中,假定大小的伪参数是一个明确的索引范围可以解决。
SUBROUTINE foo(arraylarge, indexmin, indexmax)
INTEGER, DIMENSION(10,1:20) :: arraylarge
INTEGER, INTENT(in) :: indexmin
INTEGER, INTENT(in) :: indexmax
...
! Do work from indexmin to indexmax
arraylarge(:,indexmin:indexmax) = ...
END SUBROUTINE
然后调用此子程序。
CALL foo(smallarray, 1, 5)
这似乎有多种错误,应该有未定义的行为。
smallarray
和arraylarge(:,indexmin:indexmax)
的大小相同但SIZE(small array, 2) .eq. SIZE(arraylarge(:,indexmin:indexmax),2)
具有相同的大小,但我认为应该访问未分配的内存,因为smallarray
isn& #39; t从指数1:4定义。除非它在后台执行arraylarge(:,1:5) = smallarray(:,5:10)
之类的操作。但在我看来,这将是依赖于编译器的东西。当较小的数组传递到较大的假定大小数组时会发生什么?这似乎应该导致BAD_ACCESS
条件,但它不是。
答案 0 :(得分:1)
“除非它在后台执行类似arraylarge(:,1:5) = smallarray(:,5:10)
的操作。但在我看来,这将是依赖于编译器的东西。”
确实,这种情况正在发生,并且它不依赖于编译器。数组作为形状(10,5)
的数组传递,它具有下限1
和1
。除非另有声明,否则Fortran数组的下限为1。只有allocatable
和pointer
伪参数的行为不同。因此,数组在子例程中被视为具有形状(1:10,1:5)
。
这就是它不会立即崩溃的原因。仍然将形状(1:10,1:5)
的数组传递给形状(1:10,1:20)
的伪参数不符合标准。在C中,他们称之为未定义的行为,但Fortran不使用此术语。即使在5
之后仍然无法访问元素,仍然会发生错误的事情,如果临时数组应该传递或类似。