在两层子程序中传递假设形状的数组(Fortran 90) [英] passing assumed-shape arrays in two levels of subroutines (Fortran 90)

查看:112
本文介绍了在两层子程序中传递假设形状的数组(Fortran 90)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Fortran 90中调用具有假定形状数组的连续子例程时遇到问题。更具体地说,我调用两个子例程级别,将假定形状数组作为参数传递,但最后数组丢失。为了演示,可以按照下面的代码。

 程序主体

INTERFACE
subroutine sub1(x)
real,dimension(:) :: x
real C
end subroutine sub1

subroutine sub2(x)
real, dimension(:) :: x
real C
end subroutine sub2
END INTERFACE

real,dimension(:),allocatable :: x

分配(x(1:10))! $ b $(1)= 5
调用sub1(x)
write(*,*)'result =',x(1)
deallocate(x )
结束程序main

子程序sub1(x)!第一个子程序
real,dimension(:) :: x
实数C
调用sub2(x)
结束子程序sub1

子程序sub2(x )!第二个子程序
real,dimension(:) :: x
real C
C2 = x(1)
结束子程序sub2

很快,主分配x然后调用sub1(x)。然后sub1调用sub2(x)。这意味着一个分配的数组被传递给一个将其传递给另一个子例程的子例程。我期望在sub2中有与我在main中创建的相同的数组,但不是。使用gdb作为一个工具来探索它,我得到这个:



<1>主要,在调用sub1之前,数组x是完美定义的:



(gdb)px

$ 1 =(5,0,0,0,0,0,0,0,0)


2)在sub1中,就在调用sub2之前,x也被很好的定义:

(gdb)px

$ 2 =(5,0,0,0,0,0,0,0,0,0)

3)然而,在sub2中,x有一个意外的价值甚至维度是绝对错误的:

(gdb)px

$ 3 =()

(gdb)whatis x

type = REAL(4)(0:-1)

因此,x已经成功从main传递给sub1,但不是从sub1到sub2。我一直在使用英特尔Fortran和gfortran,结果相同。



我很久以来一直在为此付出努力。任何帮助将不胜感激。

G.Oliveira。

解决方案

使用假设形状的假人参数需要一个明确的接口。
在你的主程序中,你为两个子程序提供了明确的接口,但是这些不会传播到子程序本身。即使您已将所有代码放入一个源文件,子例程也会编译为单独的单元。

这意味着sub1没有可用于sub2的显式接口,因此使用隐式接口,其中参数x被认为是一个真正的标量。



所有这些都可以通过将两个子例程放入一个模块并使用来避免在你的主程序中的这个模块,会自动提供明确的接口。这样你就不必自己提供接口了,这很容易出错。



作为一个方面说明,我建议在所有的代码中使用隐含的无。

I have had problems calling successive subroutines with assumed-shape arrays in Fortran 90. More specifically, I call two levels of subroutines, passing an assumed-shape array as a parameter, but in the end the array is lost. To demonstrate it, one can follow the code below.

  program main

  INTERFACE
     subroutine sub1(x)
       real, dimension(:):: x
       real C
     end subroutine sub1

     subroutine sub2(x)
       real, dimension(:):: x
       real C
     end subroutine sub2
  END INTERFACE

  real, dimension(:), allocatable:: x

  allocate(x(1:10)) ! First executable command in main
  x(1) = 5.
  call sub1(x)
  write(*,*) 'result = ',x(1)
  deallocate(x)
  end program main

  subroutine sub1(x) ! The first subroutine
  real, dimension(:):: x
  real C
  call sub2(x)
  end subroutine sub1

  subroutine sub2(x) ! The second subroutine
  real, dimension(:):: x
  real C
  C2=x(1)
  end subroutine sub2

Very shortly, main allocates x then call sub1(x). Then sub1 calls sub2(x). That means an allocated array is passed to a subroutine that passes it to another subroutine. I would expect to have in sub2 the same array that I've created in main, but no. Using gdb as a tool to explore it, I get this:

1) In main, just before calling sub1, the array x is perfectly defined:

(gdb) p x
$1 = (5, 0, 0, 0, 0, 0, 0, 0, 0, 0)

2) Within sub1, just before calling sub2, x is also well defined:

(gdb) p x
$2 = (5, 0, 0, 0, 0, 0, 0, 0, 0, 0)

3) Inside sub2, however, x have an unexpected value and even its dimension is absolutely wrong:

(gdb) p x
$3 = ()
(gdb) whatis x
type = REAL(4) (0:-1)

So, x has been successfully passed from main to sub1, but not from sub1 to sub2. I've been using Intel Fortran an gfortran with the same results.

I've struggling with that for a long time. Any help would be much appreciated.
G.Oliveira.

解决方案

The use of assumed-shape dummy arguments requires an explicit interface. In your main program you've provided explicit interfaces for the two subroutines, but these don't propagate into the subroutines themselves. The subroutines are compiled as separate units, even if you've put all your code into one source file.
This means that sub1 doesn't have an explicit interface available for sub2, and thus uses an implicit interface, where the argument x is assumed to be a real scalar.

All this could be avoided simply by putting the two subroutines in a module and use that module in your main program, automatically making explicit interfaces available. This way you don't have to provide the interfaces yourself, which is error prone.

As a side note, I advise the use of implicit none in ALL your code.

这篇关于在两层子程序中传递假设形状的数组(Fortran 90)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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