当虚拟指定长度时,将字符串作为参数传递

Ste*_*ini 5 string fortran fortran90

如果我有这个代码

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
Run Code Online (Sandbox Code Playgroud)

它不会编译,因为"foo2"的长度不是20,编译器会抱怨

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

如何在不修改子程序dummy len规范的情况下使这个东西工作?是否必须使用相同的长度声明一个中间变量并在调用时传递它?

M. *_* B. 7

标准语言很难理解.我读了@kemiisto引用的条款,要求长度(dummy arg) <= length(实际arg).这里长度(dummy arg) = 20length (actual arg) = 4长度(dummy arg) > length (actual arg),这是条款不允许的.该子句讨论截断实际以匹配虚拟,如果需要,不用空格填充它.

如果你替换character(len = 20)为代码将有效character(len = *) ,因为你不想修改伪参数规范的长度吗?


Wil*_*cat 2

在我看来,这就像标准的合规行为。

Fortran 2003,12.4.1.2 与虚拟数据对象关联的实际参数

如果标量虚拟参数是默认字符类型,则虚拟参数的长度 len 应小于或等于实际参数的长度。虚拟参数与实际参数最左边的 len 字符相关联。

然而gfortran只是发出警告消息

警告:实际参数的字符长度短于虚拟参数“名称”的字符长度 (4/20) (1)

看来英特尔 Fortran 编译器在这方面更符合标准。所以中间变量可能是唯一的选择。

或者实际上只是声明一个变量是选项,因为您的代码中没有变量。你有字面常量。无论如何,硬编码值都不是一个好主意。=)