在子程序中调用子程序时出错
error when calling a subroutine within subroutine
您好,我尝试在下面创建一个最小的、完整的和可验证的示例代码来强调我收到的一条错误消息。错误是“(1) 处参数 'func0' 中的类型不匹配;将 REAL(4) 传递给了 COMPLEX(4)。
我在代码中指出了 (1) 中的错误消息所在。当我尝试在另一个子例程中调用一个子例程时,就会发生这种情况。
我最初尝试将隐式 none 添加到 Sub2 中,但随后我收到一条错误消息,指出 func0、func1 没有隐式类型。
我试图遵循这个 post 的逻辑: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
我该如何解决这个错误?谢谢
(免责声明:我实际上并不了解 Fortran。这个答案是 WAG。)
在您的 Sub2
子例程中,func0
和 func1
都没有声明,它们不是参数。与代码的其他部分不同,Sub2
不包含 implicit none
指令,因此编译器假定您希望 func0
成为一个 REAL
变量,然后导致类型错误(因为 Sub1
需要一个 COMPLEX
变量)。
我无法告诉您如何解决此问题,因为您的代码从不在任何地方调用 Sub2
,但大概您必须从某处获取两个 COMPLEX
变量才能传递给 Sub1
.
这里有一些我们关心的概念:范围;协会;和继承。
问题代码中有四个作用域单元:模块sample
和三个过程(两个子例程和一个函数)。这些都是不同的,但它们之间共享一些信息。
首先查看 implicit
语句。在模块中没有 implicit
所以默认的类型规则适用于模块的范围单元。 (尽管模块中没有任何内容是隐式类型的——模块变量和函数都是显式声明的。)sub1
和 deriv
每个都有 implicit none
所以类型规则(没有隐式类型)是那里写得很清楚。
在 sub2
中指定 implicit none
时,编译器会抱怨 func0
和 func1
没有明确的类型声明;没有 implicit none
范围单元 sub2
继承其主机(模块)的类型规则,因此 func0
和 func1
是真实的。
您可以在 another question and its answers 中阅读有关范围单位和键入规则的信息。综上,模块中放入implicit none
这种 func0
和 func1
的类型将我们引向范围界定的另一个方面。 sub1
和 sub2
是完全不同的范围单位。这两个子例程可以共享有关声明的知识的唯一方法是通过关联一种形式。
这里有两种关联形式:主机关联和参数关联。
宿主关联是每个子程序都可以访问变量n
和m
。他们不引用那些变量,所以让我们忽略它们。主机关联还在 sub2
中给出了 sub1
的显式接口,它允许编译器抱怨类型不匹配。
在 sub2
的作用域单元中没有 func0
和 func1
的显式声明。这是 implicit none
生效的错误;使用默认的隐式类型规则,它们是真正的标量变量或具有真正标量结果的函数。如果你想让它们成为复杂的数组,你只需要这样声明它们。
参数关联的产生方式如下。我们将 sub1
的虚拟参数与 sub2
的实际参数相关联。这里的关键是关联:两个不同的事物碰巧指向同一个对象。这两个过程不会共享任何未在每个过程中明确说明的内容。为了能够将实际参数与那些虚拟参数相关联,sub2
的范围内必须存在一些适当的东西。目前没有任何作用。
简而言之:您需要在 sub2
中适当声明 func0
和 func1
。这些可能是局部变量或伪参数,具体取决于您希望程序如何运行。
您好,我尝试在下面创建一个最小的、完整的和可验证的示例代码来强调我收到的一条错误消息。错误是“(1) 处参数 'func0' 中的类型不匹配;将 REAL(4) 传递给了 COMPLEX(4)。
我在代码中指出了 (1) 中的错误消息所在。当我尝试在另一个子例程中调用一个子例程时,就会发生这种情况。
我最初尝试将隐式 none 添加到 Sub2 中,但随后我收到一条错误消息,指出 func0、func1 没有隐式类型。
我试图遵循这个 post 的逻辑: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
我该如何解决这个错误?谢谢
(免责声明:我实际上并不了解 Fortran。这个答案是 WAG。)
在您的 Sub2
子例程中,func0
和 func1
都没有声明,它们不是参数。与代码的其他部分不同,Sub2
不包含 implicit none
指令,因此编译器假定您希望 func0
成为一个 REAL
变量,然后导致类型错误(因为 Sub1
需要一个 COMPLEX
变量)。
我无法告诉您如何解决此问题,因为您的代码从不在任何地方调用 Sub2
,但大概您必须从某处获取两个 COMPLEX
变量才能传递给 Sub1
.
这里有一些我们关心的概念:范围;协会;和继承。
问题代码中有四个作用域单元:模块sample
和三个过程(两个子例程和一个函数)。这些都是不同的,但它们之间共享一些信息。
首先查看 implicit
语句。在模块中没有 implicit
所以默认的类型规则适用于模块的范围单元。 (尽管模块中没有任何内容是隐式类型的——模块变量和函数都是显式声明的。)sub1
和 deriv
每个都有 implicit none
所以类型规则(没有隐式类型)是那里写得很清楚。
在 sub2
中指定 implicit none
时,编译器会抱怨 func0
和 func1
没有明确的类型声明;没有 implicit none
范围单元 sub2
继承其主机(模块)的类型规则,因此 func0
和 func1
是真实的。
您可以在 another question and its answers 中阅读有关范围单位和键入规则的信息。综上,模块中放入implicit none
这种 func0
和 func1
的类型将我们引向范围界定的另一个方面。 sub1
和 sub2
是完全不同的范围单位。这两个子例程可以共享有关声明的知识的唯一方法是通过关联一种形式。
这里有两种关联形式:主机关联和参数关联。
宿主关联是每个子程序都可以访问变量n
和m
。他们不引用那些变量,所以让我们忽略它们。主机关联还在 sub2
中给出了 sub1
的显式接口,它允许编译器抱怨类型不匹配。
在 sub2
的作用域单元中没有 func0
和 func1
的显式声明。这是 implicit none
生效的错误;使用默认的隐式类型规则,它们是真正的标量变量或具有真正标量结果的函数。如果你想让它们成为复杂的数组,你只需要这样声明它们。
参数关联的产生方式如下。我们将 sub1
的虚拟参数与 sub2
的实际参数相关联。这里的关键是关联:两个不同的事物碰巧指向同一个对象。这两个过程不会共享任何未在每个过程中明确说明的内容。为了能够将实际参数与那些虚拟参数相关联,sub2
的范围内必须存在一些适当的东西。目前没有任何作用。
简而言之:您需要在 sub2
中适当声明 func0
和 func1
。这些可能是局部变量或伪参数,具体取决于您希望程序如何运行。