Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers 如何判断fortran过程指针是否与特定子例程关联_Pointers_Fortran_Procedure - Fatal编程技术网

Pointers 如何判断fortran过程指针是否与特定子例程关联

Pointers 如何判断fortran过程指针是否与特定子例程关联,pointers,fortran,procedure,Pointers,Fortran,Procedure,我想知道如何判断fortran过程指针是否与特定的子例程相关联。以下是MWE(基本上基于) 我知道关联的函数可以用来判断过程指针是否关联,但是我怎么知道它与哪个子程序关联呢?对于这里,如果bc与boundaryA或boundaryB关联 我试过了 associated(a%bc, boundaryA) 编译器(gfortran 4.8.2)给出了一个错误,即boundaryA中“associated”内在变量的“target”参数必须与“pointer”的类型和种类相同 如果删除了nopass

我想知道如何判断fortran过程指针是否与特定的子例程相关联。以下是MWE(基本上基于)

我知道关联的函数可以用来判断过程指针是否关联,但是我怎么知道它与哪个子程序关联呢?对于这里,如果bc与boundaryA或boundaryB关联

我试过了

associated(a%bc, boundaryA)
编译器(gfortran 4.8.2)给出了一个错误,即boundaryA中“associated”内在变量的“target”参数必须与“pointer”的类型和种类相同


如果删除了nopass属性,编译器会给出一个错误,即在“bc”处带有pass(i)的“bc”的参数“i”必须是派生类型“bc\u type”。

这里有一种方法

program main
use boundary
use, intrinsic :: iso_c_binding
implicit none
type(bc_type) :: a    

  a%bc => boundaryA

if (same_proc(c_funloc(a%bc),c_funloc(boundaryA))) print *, "boundaryA"
if (same_proc(c_funloc(a%bc),c_funloc(boundaryB))) print *, "boundaryB"

    contains
    function same_proc (a,b)
    use, intrinsic :: iso_c_binding
    logical same_proc
    type(c_funptr), intent(in) :: a,b

    same_proc = transfer(a,0_C_INTPTR_T) == transfer(b,0_C_INTPTR_T)
    end function same_proc


end program

它给出了一个错误“boundaryA上关联的内在函数的目标参数必须与“指针”的类型和种类相同”。很抱歉我的错误。实际上,我用了另一个示例代码。我已经改正了。主要区别在于,现在过程指针是在一个新类型“bc_type”中定义的。如果删除了nopass,编译器会给出一个错误,即带有pass(i)的'bc'的参数'i'必须是派生类型'bc_type'。现在它是类型的组件,
nopass
是必需的。然而,我尝试了gfortran 4.8.1(最接近您的版本),正如预期的那样,这是可以接受的。你有没有访问过其他(更高)版本?我在我的windows 8系统上尝试了gfortran 5.3.0,效果非常好。史蒂夫回答中的方法在这里也适用。但在我的ubuntu系统4.8.2上,这两种方法在gfortran 4.8.2中都失败了。您的方法给出了一个新的错误,即参数“a”到“c_funloc”必须是一个过程。(我使用的是gfortran 4.8.2)另外,你能解释一下“相同程序”功能的细节吗?iso_c_绑定模块、传递函数、c_funloc函数对我来说都是全新的…这在英特尔Fortran中对我很有用;可能是gfortran病毒。C_FUNLOC是在ISO_C_绑定(Fortran 2003标准的一部分)中定义的一个C可互通性函数。它接受一个过程作为参数,并返回一个指向它的指针作为C_FUNLOC类型的值。因此,对同一个_proc的调用传递两个过程的C_FUNLOC值(过程地址)进行比较。同一个_proc使用TRANSFER将这些值“强制转换”为地址大小的整数并进行比较。如果它们相同,则表示C_FUNLOC值相同。此解决方案适用于gfortran 7.3@SteveLionel:为什么
关联(a%bc,boundaryA)
不适用于英特尔编译器?它适用于gfortran 7.3,但不适用于intel 18.0.2。我们是否应该期望这在未来的版本中起作用?谢谢你,亚历克西斯,这是一个很好的问题。我不确定我为什么不早点提出这个建议。根据标准,它应该能工作。我已经从英特尔公司退休,所以我无法预测它何时会得到修复,但我会向英特尔公司报告。
program main
use boundary
use, intrinsic :: iso_c_binding
implicit none
type(bc_type) :: a    

  a%bc => boundaryA

if (same_proc(c_funloc(a%bc),c_funloc(boundaryA))) print *, "boundaryA"
if (same_proc(c_funloc(a%bc),c_funloc(boundaryB))) print *, "boundaryB"

    contains
    function same_proc (a,b)
    use, intrinsic :: iso_c_binding
    logical same_proc
    type(c_funptr), intent(in) :: a,b

    same_proc = transfer(a,0_C_INTPTR_T) == transfer(b,0_C_INTPTR_T)
    end function same_proc


end program