Границы массива с массивом нулевого размера в Fortran

При распределении массивов нулевого размера в Fortran я получаю нелогичное поведение.

Этот код:

program test_zerosized
  implicit none
  integer, allocatable :: a(:),b(:)
  allocate(a(0))
  print *, ' a lower bound = ',lbound(a,1)
  print *, ' a upper bound = ',ubound(a,1)

  allocate(b(0:0))
  print *, ' b lower bound = ',lbound(b,1)
  print *, ' b upper bound = ',ubound(b,1)
  return
end program test_zerosized

Производит следующий вывод:

  a lower bound =            1
  a upper bound =            0
  b lower bound =            0
  b upper bound =            0

Соответствует ли мой компилятор (gcc/gfortran 6.2.0) стандарту? Я не понимаю, почему lbound(a,1)==1 вместо lbound(a,1)==0, так как общий размер массива равен нулю элементов. Спасибо!


person Federico Perini    schedule 20.11.2018    source источник
comment
Хорошо, если Lbound(a) = 0 и Ubound(a) = 0, это не нулевой размер, есть 1 элемент, а именно a(0)   -  person Ian Bush    schedule 20.11.2018


Ответы (1)


Результат, который вы наблюдаете, является правильным поведением.

Массив a имеет нулевой размер, а lbound работает с такими массивами (F2008, 13.7.90) (курсив мой):

Если ARRAY – это целый массив, и либо ARRAY – это массив предполагаемого размера ранга DIM, либо размерность DIM массива имеет ненулевой размер, LBOUND (ARRAY, DIM) имеет значение, равное нижней границе нижнего индекса РАЗМЕР МАССИВА. В противном случае значение результата равно 1.

ubound работает взаимодополняющим образом.

Сравните это с массивом размера 1 b с нулевой нижней границей и нулевой верхней границей.

Распределяемый характер a не имеет значения, и вы увидите тот же результат с явным массивом формы нулевого размера.

person francescalus    schedule 20.11.2018
comment
понял, спасибо @francescalus, так что в некотором смысле стандарт требует, чтобы проверка размера на основе привязки была последовательной: для массива a size(a) == ubound(a)-lbound(a)+1 == 0-1+1 == 0, а для массива b size(b) == ubound(b)-lbound(b)+1 == 0-0+1 == 1, который содержит 1 элемент, как указал @Ian Bush - person Federico Perini; 21.11.2018
comment
Действительно (заботясь о том, чтобы рассмотреть экстенты/границы/размеры с точки зрения отдельных рангов). - person francescalus; 21.11.2018