передача строки в качестве аргумента, когда манекен имеет указанную длину - PullRequest
4 голосов
/ 24 января 2011

если у меня есть этот код

module test
contains
   subroutine xx(name)
      character(len=20), intent(in), optional :: name

      if (present(name)) then
         print *, name
      else
         print *, "foo"
      endif
   end subroutine
end module
program x
   use test

   call xx()
   call xx("foo2")
end program

Он не скомпилируется, так как "foo2" не имеет длины 20, а компилятор жалуется

test.f90(17): error #7938: Character length argument mismatch.   ['foo2']
   call xx("foo2")
-----------^

Как мне сделать эту вещьработать, не изменяя подпрограмму фиктивной спецификации len?Обязательно ли указывать промежуточную переменную такой же длины и передавать ее во время вызова?

Ответы [ 3 ]

7 голосов
/ 25 января 2011

Стандартный язык может быть трудно понять.Я прочитал приведенный @kemiisto пункт как требующий длины (dummy arg) <= length (фактический аргумент).Здесь длина (dummy arg) = 20 и length (actual arg) = 4, то есть длина (dummy arg) > length (actual arg), что не разрешено предложением.В этом пункте говорится об усечении фактического, чтобы он соответствовал фиктивной фигуре, если это необходимо, а не заполнении его пробелами.

Код будет работать, если вы замените character(len = 20) на character(len = *) Есть ли проблема с этим, посколькуне хотите изменить длину спецификации фиктивного аргумента?

2 голосов
/ 24 января 2011

Мне кажется, что стандартное поведение соответствует.

Fortran 2003, 12.4.1.2 Фактические аргументы, связанные с фиктивными объектами данных

Если скалярный фиктивный аргумент имеет тип символ по умолчанию, длина len фиктивный аргумент должен быть меньше или равна длине фактического аргумент. Пустой аргумент становится связано с крайним левым лен символы фактического аргумента.

Однако, gfortran просто выдать предупреждающее сообщение

Предупреждение: длина символа фактического аргумента короче, чем у фиктивного аргумента name (4/20) при (1)

Похоже, что компилятор Intel Fortran более соответствует стандарту в этом отношении. Так что промежуточная переменная, вероятно, единственный вариант.

Или просто объявить переменную - это опция, потому что у вас ее нет в коде. У вас есть буквальная константа. В любом случае жестко закодированные значения не очень хорошая идея. =)

1 голос
/ 03 февраля 2011

Причиной возникновения этой ошибки является то, что вашему методу разрешено читать / записывать до len=20 символов в фиктивный аргумент name.Ваш строковый литерал меньше этой суммы, и ваш компилятор предупреждает вас об этом.Даже несмотря на то, что он объявлен intent(in), вы можете читать вне фактической длины аргумента и вызвать нарушение прав доступа и т. Д.

Возможно, вам следует придерживаться len=* с фиктивными аргументами и использовать len или len_trimпри определении количества символов, которые можно читать / записывать.

Или, если вы должны оставить len=20, вам следует использовать временную переменную, используемую для передачи значений в этот метод.Или что-то более уродливое, например "hello"//repeat(" ", 15).

...