fortran 90 用户定义类型,按值传递?
我在 Fortran 90 中遇到问题。
我有一个用户定义的类型,当我调用其中一个 MPI 子例程时,数据看起来是按值传递的(而不是地址,正如我认为的那样)。输出参数未修改。它似乎特定于 MPI 调用。我在一个简单的测试中尝试了同样的事情,并且我可以更改调用范围中传入的值。我不知道为什么会这样,因为我认为 Fortran 总是按地址传递。知道会发生什么吗?
需要明确的是,注释片段显示了如何进行调用。在第一次调用中,c%NSubDomains
是一个输出参数,应该在调用范围内进行修改,但事实并非如此。当我使用数组而不是用户定义类型的成员进行调用时,它会在未注释的代码片段中起作用。
! ! This doesn't work output values aren't modified ??
! call MPI_Dims_create(c%NProcs,c%NDims,c%NSubDomains,iErr)
nsubs(:)=0
call MPI_Dims_create(c%NProcs,c%NDims,nsubs,iErr)
c%NSubDomains=nsubs
I have an issue in Fortran 90.
I have a user-defined type, and when I call one of the MPI subroutines the data looks to be passed by value (not address, as I thought it should). The output arguments aren't modified. It seems to be specific to the MPI calls. I tried the same thing in a simple test, and I can change the passed in values in the calling scope. I'm not sure why this is, because I thought Fortran always passes by address. Any idea what could be going on?
Just to be clear, the commented snippet shows how the calls are made. In the first call, c%NSubDomains
is an output argument and should be modified in the calling scope, but is not. When I call with an array rather than a member of a user-defined type it works, in the uncommented snippet.
! ! This doesn't work output values aren't modified ??
! call MPI_Dims_create(c%NProcs,c%NDims,c%NSubDomains,iErr)
nsubs(:)=0
call MPI_Dims_create(c%NProcs,c%NDims,nsubs,iErr)
c%NSubDomains=nsubs
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Fortran 语言标准没有说明如何传递参数。不同的编译器可以以不同的方式实现参数传递,具体取决于参数的类型和参数的“意图”(in/out/inout)。
nsubs 与 C%NSubDomains 是如何声明的?您是否有一个接口声明(可能来自与 MPI 的 Fortran 90 绑定)来告诉编译器应该如何调用 MPI_Dims_create?
The Fortran language standard doesn't say how arguments are passed. Different compilers can implement argument passing in various ways, depending on the type of the argument and the "intent" of the argument (in/out/inout).
How are nsubs versus C%NSubDomains declared? Do you have an interface declaration (probably from a Fortran 90 binding to MPI) to tell the compiler how it is supposed to call MPI_Dims_create?
正如 @MSB 所观察到的,Fortran 标准并不强制要求如何实现参数传递。不过,我认为很明显,它们确实要求参数传递的语义使程序员看起来好像参数是通过引用传递的。因此,我理解 OP 的不安,因为
MPI_DIMS_CREATE
的INTENT(OUT)
参数似乎并非如此。如果您的编译器支持如下声明的语法:
或者如果您使用的编译器实现了 Fortran 2003 的 C 互操作性功能,则您可能能够强制编译器像通过引用一样传递组件。但是,如果您这样做,编译器很可能在幕后生成代码来执行您自己在未注释的代码中所做的事情 - 创建一个可以像通过引用一样传递的变量并将其传递给子例程。
在这种情况下,我会顺其自然并自己编写代码。
As @MSB observes the Fortran standards don't mandate how argument passing is to be implemented. I think it's clear, though, that they do mandate that the semantics of argument passing make it look to the programmer as if arguments are passed by reference. So I understand OP's upset that this appears not to be the case for the
INTENT(OUT)
argument ofMPI_DIMS_CREATE
.If your compiler supports the syntax of declarations like this:
or if you are using a compiler with the C-interoperability features of Fortran 2003 implemented, you might be able to coerce the compiler into passing the component as if by reference. However, if you do, it is highly likely that behind the scenes the compiler is generating code to do what you yourself are doing in your uncommented code -- making a variable which can be passed as if by reference and passing that to the subroutine.
In this situation I'd go with the flow and write the code myself.