String 当虚拟对象具有指定的长度时,将字符串作为参数传递
如果我有这个密码String 当虚拟对象具有指定的长度时,将字符串作为参数传递,string,fortran,fortran90,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
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")
-----------^
在不修改子例程dummy len规范的情况下,我如何使这件事情工作?是否必须声明具有相同长度的中间变量,并在调用时传递该变量?在我看来,这类似于标准兼容行为 Fortran 2003,12.4.1.2与虚拟数据对象相关的实际参数 如果标量伪参数的类型为 默认字符,长度len为 伪参数应小于 或等于实际长度 论点伪参数变为 与最左边的len关联 实际参数的字符 然而,格弗特兰只是发出了一条警告信息 警告:实际参数的字符长度小于(1)处伪参数“name”(4/20)的字符长度 在这方面,“英特尔Fortran编译器”似乎更符合标准。所以中间变量可能是唯一的选择
或者实际上仅仅声明一个变量是一个选项,因为您的代码中没有变量。你有文字常数。硬编码值无论如何都不是一个好主意。=) 标准语言可能很难理解。我阅读了@kemiisto引用的条款,该条款要求长度
(虚拟arg)长度(实际arg)
,该条款不允许。该条款讨论了截断实际值以匹配虚拟值(如果需要),而不是用空格填充
如果将
字符(len=20)
替换为字符(len=*),则代码将正常工作
由于您不想修改伪参数规范的长度,这是否有问题?发生此错误的原因是允许您的方法向伪参数名称
最多读取/写入len=20
个字符。您的字符串文字量小于此数量,并且编译器正在提醒您这一事实。即使它被声明为intent(in)
,您也可以读取超出实际参数长度的内容,并导致访问冲突等
您可能应该使用伪参数坚持使用len=*
,并在确定安全读写的字符数时使用len
或len\u trim
或者,如果必须保留
len=20
,则应使用临时变量将值传递给该方法。或者像“hello”//repeat(“,15)
这样更难看的问题是,带有字符(len=20)的例程位于我不应该修改的代码的一部分。然后我建议编写一个“glue”函数,将其参数转换为字符(len=20)并将此函数应用于xx的任何可能不够长的参数:调用xx(makelen20(“foo2”))