在子程序中调用子程序时出错

时间:2017-04-30 17:12:29

标签: fortran subroutine

您好我尝试在下面创建一个最小,完整且可验证的示例示例代码,以强调我收到的一条错误消息。错误是"参数' func0'中的类型不匹配在(1);将REAL(4)传递给COMPLEX(4)。

我在代码中指出了来自(1)的错误消息。当我尝试在另一个子例程中调用子例程时,会发生这种情况。

我最初尝试将隐式none添加到Sub2中,但是后来我收到一条错误消息,说func0,func1没有隐式类型。

我试图遵循这篇文章的逻辑:How to call and use a subroutine inside another subroutine in fortran?

Module Sample

integer :: n,m

contains 

subroutine Sub1(func0,func1)

implicit none

   complex, dimension(-10:10, -10:10), intent(inout) :: func0,func1
   complex, dimension(-10:10, -10:10) :: Deriv0,Deriv1


     do while (100 > 0.000001) 

        Deriv0 = Deriv(func0)
        Deriv1 = Deriv(func1)

     end do

end subroutine Sub1

subroutine Sub2(func3)
!implicit none : if this line is not commented out, I still get error messages saying func0,func1 do not have implicit types

   real,dimension(0:20), intent(inout) :: Func3

   call Sub1(func0,func1) !error message from here, this is line (1)

end subroutine  Sub2

function Deriv(func)
implicit none

complex, dimension(-10:10, -10:10) :: func, Deriv

   do n=-9,9
   do m=-9,9

     Deriv(n,m) = func(n+1,m)-2*func(n,m)

   end do
   end do

end function Deriv

End Module Sample

如何修复此错误?感谢。

2 个答案:

答案 0 :(得分:2)

我们关注的是一些概念:范围界定;协会;和继承。

在问题的代码中有四个范围单元:模块sample和三个程序(两个子程序和一个函数)。这些都是截然不同的,但是它们之间共享了一些信息。

首先查看implicit声明。在模块中没有implicit因此默认的输入规则适用于模块的范围单元。 (虽然模块中没有任何内容是隐式输入的 - 模块变量和函数都是显式声明的。)sub1deriv每个都有implicit none所以输入规则(没有隐式输入)是在那里清楚地说明了。

implicit none中指定了sub2时,编译器投诉没有func0func1的明确类型声明;如果没有implicit none范围单元sub2,则会继承其主机(模块)的输入规则,因此func0func1是真实的。

您可以在another question and its answers中阅读有关作用域单位和输入规则的信息。总之,将implicit none放在模块中。

这种func0func1的输入引导我们进行范围界定的另一个方面。 sub1sub2是完全不同的范围单位。这两个子程序可以分享关于声明的知识的唯一方法是通过一种形式的关联。

这里有两种形式的关联:主机关联和参数关联。

主机关联是每个子例程都可以访问变量nm。他们没有引用这些变量,所以让我们忽略它们。主机关联还在sub1中提供sub2的显式接口,允许编译器抱怨类型不匹配。

sub2的范围单元中,没有明确声明func0func1。这是implicit none生效的错误;使用默认的隐式类型规则,它们是真正的标量变量或具有真实标量结果的函数。如果你希望它们是复杂的数组,那么你只需要声明它们就好了。

论证关联以下列方式出现。我们将sub1的伪参数与sub2的实际参数相关联。这里至关重要的是 association :两个不同的事情恰好引用同一个对象。这两个程序并不共享任何在每个程序中明确说明的内容。为了能够在sub2的范围内存在与这些虚拟参数相关联的实际参数,必须存在适当的参数。目前没什么。

简而言之:您需要在func0中提供合适的func1sub2声明。这些可能是局部变量或伪参数,具体取决于您希望程序如何流动。

答案 1 :(得分:0)

(免责声明:我实际上并不认识Fortran。这个答案是WAG。)

Sub2子例程中,func0func1均未声明,且它们不是参数。与代码的其他部分不同,Sub2不包含implicit none指令,因此编译器假定您将func0作为REAL变量,然后导致类型错误(因为Sub1需要COMPLEX变量)。

我无法告诉您如何解决这个问题,因为您的代码从不在任何地方调用Sub2,但可能您必须从某个地方获取两个COMPLEX个变量才能传递给Sub1。< / p>