作为函数参数的类型数组内的数组 [英] Array inside type array as function argument

查看:166
本文介绍了作为函数参数的类型数组内的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  program foo 
type bar
real,dimension( 2):: vector
结束类型
类型(bar),dimension(3):: bararray
调用doSomething(bararray%vector)
结束程序

子程序doSomething(v)
实数,维(3,2),意图(inout):: v
...
结束子程序



现在这给我一个编译错误。

 错误:不能在(1)

中指定两个或多个非零位的零件引用如果我将呼叫改为

  call doSomething((/ bararray%vector(1),bararray%vector(2)/))

一切都很好。问题是,这看起来有点麻烦,所以问题是,有没有其他方法可以为子程序写参数?



预先感谢。

因为存在一个约束(在F2008中,语法规则是C618),这种错误出现在结构中只有一个部分的语言中组件(或类似的多部件参考)可以具有非零的等级。您对结构组件的引用 bararray%vector 具有非零级别的两部分 - 组件 vector 和变量 bararray



(在更改调用方法中,对组件向量的引用有一个下标,那部分总体等级为零,因此接受bararray%vector(1)。)

改变呼叫方法存在一个重大的潜在问题。

子例程中的哑元参数是 INTENT(INOUT)。这就要求实际的论点是可以定义的(一个变量实际上可以是变化的)。

在您的更改调用方法中,与该伪参数关联的实际参数是表达式 - 数组构造函数。表达式是不可定义的 - 评估它们的结果是一个值,而不是可以定义的东西 - 也就是说,你不能明确地说 2 + 2 = 6

假设在真正的代码中,doSomething子程序是一个外部程序,所以你的编译器没有诊断出这个。如果doSomething有明确的接口(因为它可能位于模块中),那么我希望编译器报告一个错误。

在调用之前编组数据(将数据复制到适当大小的数组变量中,调用过程,复制数据)。重写子例程的接口以获取类型栏的对象(将该类型的定义移至模块)显然是另一种可能性。派生类型不仅是存储数据的便捷方式,它们通常是处理数据的便捷方式。



我会非常警惕那些试图欺骗处理器接受你所知道的假设数组布局的方法 bararray %vector 在内存中。类型和数组的布局可能因处理器而异,另外随着处理器错误检查的改进,这种技巧可能会导致以后的诊断。供应商提供的图书馆可以逃脱这种伎俩,但不是我们仅仅编程凡人。


I have the following program at hand

program foo
  type bar
    real, dimension(2) :: vector
  end type
  type(bar), dimension(3) :: bararray
  call doSomething(bararray%vector)
end program

subroutine doSomething(v)
  real, dimension(3,2), intent(inout) :: v
  ...
end subroutine

Now this gives me a compilation error.

Error: Two or more part references with nonzero rank must not be specified at (1)

If I change the call to

call doSomething((/bararray%vector(1), bararray%vector(2)/))

everything works out nicely. The thing is that this just seems a bit cumbersome, so the question is, is there any other way to write the argument for the subroutine?

Thanks in advance.

解决方案

The error arises because there is a constraint (in F2008 the syntax rule is C618) in the language that only one part in a structure component (or similar multi-part reference) may have non-zero rank. Your reference bararray%vector to the structure component has two parts with non-zero rank - the component vector and the variable bararray.

(In the "change the call" approach the references to the component vector have a subscript that gives that part an overall rank of zero, hence bararray%vector(1) is accepted.)

There is a significant latent problem with the "change the call" approach.

The dummy argument in the subroutine is INTENT(INOUT). That requires the actual argument to be definable (a variable that can actually be "varied").

In your "change the call" approach the actual argument associated with that dummy argument is an expression - an array constructor. Expressions are not definable - the result of evaluating them is a value and not something that can be "defined" - i.e. you can't sanely say 2 + 2 = 6.

Presumably in the real code the doSomething subroutine is an external procedure, so your compiler has not diagnosed this. If doSomething had an explicit interface (because it was in a module, perhaps) then I would expect the compiler to report an error.

Others have suggested the approach of re-marshalling your data prior to the call (copy data into an array variable of the appropriate size, call the procedure, copy the data out). Rewriting the interface of the subroutine to take objects of type bar (with the definition of the type moved to a module) is obviously another possibility. Derived types are not only a convenient way of storing data, they are often a convenient way of working with data.

I would be very wary of approaches that attempted to trick the processor into accepting what you "know" to be the layout of the hypothetical array bararray%vector in memory. The layout of types and arrays can change from processor to processor, plus as processor error checking improves that sort of trick may result in later diagnostics. Vendor supplied libraries can get away with that sort of trick, but not us mere programming mortals.

这篇关于作为函数参数的类型数组内的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆