当虚拟对象具有指定长度时传递字符串作为参数
如果我有这段代码,
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 规范的情况下使这个东西工作?是否必须声明具有相同长度的中间变量并在调用时传递该变量?
if I have this code
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
It will not compile since "foo2" is not of length 20, and the compiler complains
test.f90(17): error #7938: Character length argument mismatch. ['foo2']
call xx("foo2")
-----------^
How can I make this thing work, without modifying the subroutine dummy len specification ? Is it mandatory to have an intermediate variable declared with the same length and pass that at call time ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
发生此错误的原因是您的方法允许在虚拟参数
name
中读取/写入最多len=20
个字符。您的字符串文字小于此数量,并且您的编译器会警告您这一事实。即使它被声明为intent(in)
,您也可能会读取超出实际参数长度的内容并导致访问冲突等。您可能应该坚持使用带有虚拟参数的
len=*
并在确定可以安全读/写的字符数时使用 len 或 len_trim 。或者,如果您必须保留
len=20
,则应使用临时变量来将值传递到该方法中。或者一些更难看的东西,比如"hello"//repeat(" ", 15)
。The reason this error occurs is your method is allowed to read/write up to
len=20
characters to the dummy argumentname
. Your string literal is less than this amount and your compiler is alerting you to this fact. Even though it is declaredintent(in)
you could read beyond the actual argument length and cause an access violation, etc.You should probably stick to
len=*
with dummy arguments and uselen
orlen_trim
when determining how many characters it is safe to read/write.Or if you must keep the
len=20
, you should use a temporary variable used to pass values into that method. Or something uglier like"hello"//repeat(" ", 15)
.在我看来,这就像标准的合规行为。
Fortran 2003,12.4.1.2 与虚拟数据对象关联的实际参数
然而gfortran只是发出警告消息
看来英特尔 Fortran 编译器在这方面更符合标准。所以中间变量可能是唯一的选择。
或者实际上只是声明一个变量是选项,因为您的代码中没有变量。你有字面常量。无论如何,硬编码值都不是一个好主意。 =)
Seems to me like standard compliant behavior.
Fortran 2003, 12.4.1.2 Actual arguments associated with dummy data objects
However gfortran just rise a warning message
It seems that Intel Fortran compiler is more standard compliant in that respect. So intermediate variable is probably the only option.
Or actually just declaring a variable is option because you do not have one in your code. You have literal constant. Hard-coded values are not a good idea anyway. =)
标准语言可能难以理解。我读到 @kemiisto 引用的子句要求长度
(dummy arg) <= length
(actual arg)。这里长度(dummy arg) = 20
并且length(actual arg) = 4
,所以长度(dummy arg) > length (actual arg)
,子句不允许这样做。该子句讨论了如果需要的话,截断实际值以匹配虚拟值,而不是用空格填充。如果您将
character(len = 20)
替换为character(len = *)
,该代码将起作用。这是否有问题,因为您不想修改长度虚拟参数规范?Standard language can be hard to understand. I read the clause cited by @kemiisto as requiring length
(dummy arg) <= length
(actual arg). Here length(dummy arg) = 20
andlength (actual arg) = 4
, so length(dummy arg) > length (actual arg)
, which is not allowed by the clause. The clause talks about truncating the actual to match the dummy, if needed, not padding it with blanks.The code will work if you replace
character(len = 20)
withcharacter(len = *)
Is there a problem with this since you didn't want to modify the length of the dummy argument specification?