当虚拟对象具有指定长度时传递字符串作为参数

发布于 2024-10-13 11:36:24 字数 577 浏览 3 评论 0原文

如果我有这段代码,

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

指尖微凉心微凉 2024-10-20 11:36:25

发生此错误的原因是您的方法允许在虚拟参数 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 argument name. Your string literal is less than this amount and your compiler is alerting you to this fact. Even though it is declared intent(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 use len or len_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).

网白 2024-10-20 11:36:25

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

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

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

然而gfortran只是发出警告消息

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

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

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

Seems to me like standard compliant behavior.

Fortran 2003, 12.4.1.2 Actual arguments associated with dummy data objects

If a scalar dummy argument is of type
default character, the length len of
the dummy argument shall be less than
or equal to the length of the actual
argument. The dummy argument becomes
associated with the leftmost len
characters of the actual argument.

However gfortran just rise a warning message

Warning: Character length of actual argument shorter than of dummy argument 'name' (4/20) at (1)

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. =)

夕嗳→ 2024-10-20 11:36:24

标准语言可能难以理解。我读到 @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 and length (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) with character(len = *) Is there a problem with this since you didn't want to modify the length of the dummy argument specification?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文