You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ifort关联派生类型指针时associated函数意外返回false问题

Fortran中associated(ptr, target)在ifort下返回false的问题分析与解决

我编写了一段Fortran程序,将指针关联到派生类型实例后,用associated()函数检测指针是否与目标对象关联。使用gfortran 9.2.0编译时,associated()按预期返回true;但用ifort 19.0.4.243编译时,带目标参数的associated(ptr, obj)返回false。

程序代码

module mod_pointer_association

  type mytype
  end type mytype

contains

  subroutine test_association(obj)

    class(mytype), target, intent(in)::obj
    class(mytype), pointer::ptr

    ptr=>obj

    if (.not. associated(ptr)) then
       print *, "ptr not associated"
       error stop
    end if

    if (.not. associated(ptr, obj)) then
       print *, "ptr not associated with obj"
       error stop
    end if

  end subroutine test_association

end module mod_pointer_association

program test_pointer_assocation

  use mod_pointer_association

  type(mytype), target::myobj

  call test_association(myobj)

end program test_pointer_assocation

运行结果

  • gfortran编译运行无输出,符合预期;
  • ifort编译运行输出:
$ ./test_pointer_association 
 ptr not associated with obj

问题原因

这个问题源于ifort对多态对象指针关联检测的处理逻辑:当obj是class(mytype)类型的多态哑元时,ifort在参数传递过程中会对多态实参执行装箱操作,创建临时对象,导致子例程内obj的内存地址与原始对象myobj的地址不一致。而ptr关联的是原始对象的地址,因此associated(ptr, obj)会返回false。

解决方案

有三种可行的解决方式:

  1. 改用多态指针作为子例程哑元
    将子例程的哑元改为多态指针类型,直接传递原始对象的指针,避免临时对象的创建。修改后的代码如下:
module mod_pointer_association

  type mytype
  end type mytype

contains

  subroutine test_association(obj_ptr)

    class(mytype), pointer, intent(in)::obj_ptr
    class(mytype), pointer::ptr

    ptr=>obj_ptr

    if (.not. associated(ptr)) then
       print *, "ptr not associated"
       error stop
    end if

    if (.not. associated(ptr, obj_ptr)) then
       print *, "ptr not associated with obj"
       error stop
    end if

  end subroutine test_association

end module mod_pointer_association

program test_pointer_assocation

  use mod_pointer_association

  type(mytype), target::myobj
  class(mytype), pointer::obj_ptr

  obj_ptr => myobj
  call test_association(obj_ptr)

end program test_pointer_assocation
  1. 通过地址比较替代associated()
    引入iso_c_binding模块,使用c_loc()函数获取指针地址,直接比较地址是否一致:
module mod_pointer_association
  use iso_c_binding
  type mytype
  end type mytype

contains

  subroutine test_association(obj)

    class(mytype), target, intent(in)::obj
    class(mytype), pointer::ptr

    ptr=>obj

    if (.not. associated(ptr)) then
       print *, "ptr not associated"
       error stop
    end if

    if (.not. (c_loc(ptr) == c_loc(obj))) then
       print *, "ptr not associated with obj"
       error stop
    end if

  end subroutine test_association

end module mod_pointer_association

program test_pointer_assocation

  use mod_pointer_association

  type(mytype), target::myobj

  call test_association(myobj)

end program test_pointer_assocation
  1. 升级ifort版本
    较新版本的ifort(如2021及以后)已经修复了这个多态对象指针关联检测的bug,升级编译器后原始代码即可正常运行。

内容的提问来源于stack exchange,提问作者jhaiduce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:33:42