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
gfortran和ifort在函数返回派生类型上的不同行为_Fortran_Gfortran_Intel Fortran_Fortran Iso C Binding_Derived Types - Fatal编程技术网

gfortran和ifort在函数返回派生类型上的不同行为

gfortran和ifort在函数返回派生类型上的不同行为,fortran,gfortran,intel-fortran,fortran-iso-c-binding,derived-types,Fortran,Gfortran,Intel Fortran,Fortran Iso C Binding,Derived Types,我正在从事一个项目,该项目需要在Fortran中存储派生类型属性的内存地址。在gfortran中,如果返回是派生类型,则存在函数返回的隐式副本。所以我存储的地址毫无意义。有一段代码: module atest ! use iso_c_binding type test real(8):: a real(8):: p end type test interface subroutine pointerprint(a) real(8), intent

我正在从事一个项目,该项目需要在Fortran中存储派生类型属性的内存地址。在gfortran中,如果返回是派生类型,则存在函数返回的隐式副本。所以我存储的地址毫无意义。有一段代码:

module atest
!  use iso_c_binding
  type test
    real(8):: a
    real(8):: p
  end type test
  interface
    subroutine pointerprint(a)
      real(8), intent(in) :: a
    end subroutine pointerprint
  end interface
  interface assignment(=)
    module procedure overloadedAsgn
  end interface
contains
  function returnvalue(t)
    type(test), intent(in)::t
    type(test):: returnvalue
    returnvalue%a=t%a+1
    call pointerprint(returnvalue%a)
  end function returnvalue
  SUBROUTINE overloadedAsgn(ret,rhs)
    type(test), intent(inout) :: ret
    type(test), intent(in) :: rhs
    print *, "assign_d"
    ret%a=rhs%a
    ret%p=rhs%p+1.0d0
    call pointerprint(rhs%a)
  end SUBROUTINE overloadedAsgn  

end module

program xxx
  use atest
  type(test):: t
  type(test):: b
  t%a=1.0d0/11.0d0
  t%p=0.0d0
  b=returnvalue(t)
end program 


#include<stdio.h>
void pointerprint_(double *x){
  printf("Addr<%lx>\n",(unsigned long)x);
}
模块测试
!  使用iso_c_绑定
型式试验
雷亚尔(8):a
雷亚尔(8)::p
端部型式试验
接口
子程序指针打印(a)
真实(8),意图(in)::a
结束子例程指针打印
端接口
接口分配(=)
模块过程重载
端接口
包含
函数返回值(t)
类型(试验),意图(in)::t
类型(测试):返回值
返回值%a=t%a+1
调用点打印(返回值%a)
结束函数返回值
子程序重载ADASGN(ret,rhs)
类型(测试)、意图(输入):ret
类型(测试),意图(in)::rhs
打印*,“分配”
ret%a=rhs%a
ret%p=rhs%p+1.0d0
调用点打印(rhs%a)
结束子例程重载ADASGN
端模块
程序xxx
使用atest
型式(试验):t
型式(试验):b
t%a=1.0d0/11.0d0
t%p=0.0d0
b=返回值(t)
结束程序
#包括
无效指针打印(双*x){
printf(“Addr\n”,(无符号长)x);
}
使用gfortran的输出为:

Addr<7fff51df24e0>
 assign_d
Addr<7fff51df2520>
Addr
分配
地址
使用ifort的输出为:

Addr<7fffc92e6fc0>
 assign_d
Addr<7fffc92e6fc0>
Addr
分配
地址

有没有办法避免gfortran中出现这样的副本,从而使结果保持一致?我刚开始学fortran。可能有函数的描述符或编译器的选项。

您指望的是处理器相关的行为。如果处理器有利可图,它可以通过拷贝传入(和/或传出)。可以使用指针伪参数传递指针


您的代码中没有任何
目标
,仍然希望依赖指向变量的指针。

您依赖于处理器相关的行为。如果处理器有利可图,它可以通过拷贝传入(和/或传出)。可以使用指针伪参数传递指针


您的代码中没有任何
目标
,仍然希望依赖指向变量的指针。

如果注释掉了
使用iso_C_绑定
,您如何调用该C代码?我担心的是C代码接口中的某些东西是差异的根源。如果您已注释掉
使用iso_C_绑定
,您将如何调用该C代码?我关心的是C代码接口中的某些东西是差异的根源。这很有趣!你能详细说明一下吗?(或者给我一个链接/一本书,我可以在那里读到这方面的内容?)对于gfortran特定的约定,请参见我推荐的Fortran 2008标准和信息性附录。对于这种情况,第C.9.4节是相关的(关于伪参数指针的可用性和
target
属性)。啊,我明白了-这是缺少的
target
,因此编译器可以自由地进行优化,而不是将其视为指针。所以我的答案肯定是错的。谢谢这很有趣!你能详细说明一下吗?(或者给我一个链接/一本书,我可以在那里读到这方面的内容?)对于gfortran特定的约定,请参见我推荐的Fortran 2008标准和信息性附录。对于这种情况,第C.9.4节是相关的(关于伪参数指针的可用性和
target
属性)。啊,我明白了-这是缺少的
target
,因此编译器可以自由地进行优化,而不是将其视为指针。所以我的答案肯定是错的。谢谢