Отсутствие подъема скалярных аргументов для массивов в Фортране - PullRequest
3 голосов
/ 18 октября 2011

Почему Fortran будет преобразовывать скалярное выражение в массив в выражении , но не в качестве аргумента процедуры? В частности, почему орган по стандартизации принял это проектное решение? Только из-за двусмысленности, процедура должна быть перегружена? Может ли сообщение об ошибке в этой ситуации быть альтернативным подходом?

Например, в приведенном ниже коде последний оператор x = foo(7) выдает ошибку GFortran: Error: Rank mismatch in argument 'a' at (1) (1 and 0).

module m

  public :: foo

  contains

  function foo(a) result(b)
    integer, dimension(:)       :: a
    integer, dimension(size(a)) :: b
    b = a+1
  end function foo

end module m

program p

  use m

  integer, dimension(4) :: x
  integer, parameter, dimension(4) :: y = (/1,2,3,4/)

  x = 7
  x = foo(x)
  x = foo(y)
  x = foo(x + 7)
  x = foo(7)

end program p

Этот вопрос должен был задать вопрос о том, почему присвоение массива будет продвигать источник скалярного значения к цели массива; в отличие от функции массива. Я ожидаю, что это просто удобный особый случай. Любые комментарии с благодарностью получены в шапках для подаяний ниже.

Ответы [ 3 ]

4 голосов
/ 18 октября 2011

Если вы хотите, чтобы функция обрабатывала аргументы масштабатора и массива, объявите ее как «элементальную» и с фиктивными аргументами масштабатора. Тогда он сможет обрабатывать как фактические аргументы масштабатора, так и массива, включая выражения масштабатора. Будет ли это удовлетворить ваши потребности?

Изменение:

  elemental function foo(a) result(b)
    integer, intent (in)      :: a
    integer :: b
    b = a+1
  end function foo

Возможно, они предоставили способ сделать то, что вы хотите, и одного способа было достаточно?

3 голосов
/ 18 октября 2011

Вызов процедуры в Fortran с явными интерфейсами (который вы получаете автоматически при использовании процедур модуля) требует соответствия TKR (тип, вид, ранг).Поскольку массив имеет тип, отличный от скаляра, не говоря уже о несоответствии рангов, это недопустимо.

Из-за неоднозначности должна быть перегружена процедура?1006 * Это было бы проблемой, да.

Может ли сообщение об ошибке в этой ситуации быть альтернативным подходом?

Могут ли существовать розовые единороги?Возможно, но, насколько мне известно, они этого не делают.Таким образом, стандарт Fortran в настоящее время требует соответствия TKR, и, следовательно, стандартный соответствующий компилятор должен обеспечить выполнение этого требования.Если вы хотите изменить это, я рекомендую внести предложение в комитет по стандартам.

0 голосов
/ 18 октября 2011

Я думаю, что ответ на этот вопрос довольно ясен. Давайте немного изменим ваш пример:

module m

  public :: foo

  contains

  function foo(a) result(b)
    integer, dimension(:)       :: a
    integer, dimension(size(a)) :: b
    b = a+1
    a(2) = -777     ! new line; modify one element
  end function foo

end module m

program p

  use m

  integer :: x
  integer, dimension(4) :: y 

  x = 7
  y = foo(x)  ! pass a scalar

end program p

что должно быть x после вызова foo?

Теперь, конечно, вы можете изменить семантику передачи аргументов в зависимости от того, является ли она intent(in) переменной, но это не что-то, что собирается уточнить вещи для программистов.

Если вызов функции должен как-то «распределяться» по элементам массива, то, как указывает MSB, элементал - это путь. В противном случае просто убедитесь, что его аргументы соответствуют параметрам.

...