将较小的数组传递给较大的假定大小数组

时间:2016-09-26 20:38:09

标签: arrays fortran

我在其他人的代码中遇到了一些似乎应该是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)

这似乎有多种错误,应该有未定义的行为。

  1. 我希望将较小尺寸的数组传递给较大尺寸的假定数组意味着子程序中的一些索引将是无效的内存位置。
  2. 虽然smallarrayarraylarge(:,indexmin:indexmax)的大小相同但SIZE(small array, 2) .eq. SIZE(arraylarge(:,indexmin:indexmax),2)具有相同的大小,但我认为应该访问未分配的内存,因为smallarray isn& #39; t从指数1:4定义。除非它在后台执行arraylarge(:,1:5) = smallarray(:,5:10)之类的操作。但在我看来,这将是依赖于编译器的东西。
  3. 当较小的数组传递到较大的假定大小数组时会发生什么?这似乎应该导致BAD_ACCESS条件,但它不是。

1 个答案:

答案 0 :(得分:1)

“除非它在后台执行类似arraylarge(:,1:5) = smallarray(:,5:10)的操作。但在我看来,这将是依赖于编译器的东西。”

确实,这种情况正在发生,并且它不依赖于编译器。数组作为形状(10,5)的数组传递,它具有下限11。除非另有声明,否则Fortran数组的下限为1。只有allocatablepointer伪参数的行为不同。因此,数组在子例程中被视为具有形状(1:10,1:5)

这就是它不会立即崩溃的原因。仍然将形状(1:10,1:5)的数组传递给形状(1:10,1:20)的伪参数不符合标准。在C中,他们称之为未定义的行为,但Fortran不使用此术语。即使在5之后仍然无法访问元素,仍然会发生错误的事情,如果临时数组应该传递或类似。