gfortran和ifort在函数返回派生类型上的不同行为
我正在从事一个项目,该项目需要在Fortran中存储派生类型属性的内存地址。在gfortran中,如果返回是派生类型,则存在函数返回的隐式副本。所以我存储的地址毫无意义。有一段代码: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
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
,因此编译器可以自由地进行优化,而不是将其视为指针。所以我的答案肯定是错的。谢谢