我正在尝试调试一些代码,其中用户定义的对象的成员神秘地改变地址,并且在这样做时我意识到用户定义的对象也这样做。这是从创建它的函数查询对象地址然后从其成员函数查询对象地址的一个小例子:
module foo_module
type foo_type
contains
procedure :: foo
end type foo_type
contains
subroutine foo(this)
class(foo_type) :: this
print *, 'Inside foo this is', loc(this)
end subroutine foo
end module foo_module
program trial
use foo_module
type(foo_type) :: object
print *, 'Object address', loc(object)
call object%foo()
end program trial
我得到的样本输出是:
Object address 4452052800
Inside foo this is 140734643354880
为什么我为同一个对象获取两个不同的地址?难道我做错了什么?或者有什么东西与LOC发挥作用我不明白?
我在osx下使用ifort。
答案 0 :(得分:2)
LOC是一个扩展名。其行为与编译器供应商指定的一样。
供应商在此处所表达的行为并不清楚,但您看到的区别在于,在主程序中,您获得了非多态对象的内存地址的整数等价物(您可能期望的) ,在子程序中,你得到对象的多态描述符的内存地址的整数等价物(也许你想要的,也许不是)。
使用TRANSFER(C_LOC(xxx),0_C_INTPTR_T)是获取对象地址的整数表示的更便携方式(其中C_ *事物来自ISO_C_BINDING内在模块)。 C_LOC要求其参数具有TARGET属性并且是非多态的(使用SELECT TYPE)。
如果您想进一步澄清LOC扩展的预期行为,我建议您询问相关的Intel Forum。
答案 1 :(得分:0)
我向开发人员报告了我们的内部问题ID为DPD200253159的错误。我发现ISO_C_BINDING的C_LOC函数有效。例如:
subroutine foo(this)
use, intrinsic :: iso_c_binding
class(foo_type) :: this
print *, 'Inside foo this is', transfer(c_loc(this),0_C_INTPTR_T)
end subroutine foo