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

Fortran求根子程序报错时如何输出传入的实际目标函数名

问题结论

Fortran 标准原生不支持自动获取作为参数传入的过程的源代码名称:过程作为实参传递时仅传递执行入口地址,不会携带函数名这类源代码层面的元数据,无法在mysolver内部直接解析出传入的FN对应的实际函数名。

可落地实现方案

最通用、可移植性最好的方式是为子程序额外增加一个字符串类型的入参,由调用方显式传入目标函数的名称,报错时直接输出该字符串即可。

修改后的子程序代码

subroutine mysolver(xl,xr,FN, fname, x_sol)
    real, intent(inout)       :: xl,xr
    real, intent(out)         :: x_sol
    real                      :: fl,fr
    ! 新增:用于接收目标函数名称的字符串参数
    character(len=*), intent(in) :: fname
    interface
        real function FN(y)
            real, intent(in)           :: y
        end function FN
    end interface
    fl = FN(xl)
    fr = FN(xr)
    if (fl*fr > 0.0) then
        ! 输出时用trim去掉字符串尾部多余空格
        print *, 'Error solving function ', trim(fname)
    end if
        
    ! 其余原有求解逻辑保持不变        
end subroutine mysolver

调用方式

调用求解器时,把对应目标函数的名字作为字符串传入即可:

! 假设存在两个待求解的目标函数func1、func2
! 求解func1时
call mysolver(xl, xr, func1, 'func1', x_sol1)
! 求解func2时
call mysolver(xl, xr, func2, 'func2', x_sol2)

简化写法(依赖预处理,非标准特性)

如果不想每次手动输入函数名字符串,可以开启编译器的预处理支持,用宏做一层封装自动填充函数名字符串,以常用的C预处理器(绝大多数Fortran编译器都支持)为例:

! 注意:开启预处理时该宏定义要写在函数声明之前
#define MYSOLVER(xl, xr, fn, x_sol) mysolver(xl, xr, fn, #fn, x_sol)

封装后调用时不需要手动写名字符串,直接写:

call MYSOLVER(xl, xr, func1, x_sol1)
call MYSOLVER(xl, xr, func2, x_sol2)

预处理器会自动把#fn替换为对应实参的字符串形式"func1"/"func2"。注意该方案依赖编译器预处理能力,跨编译器时需要确认适配性。

不推荐尝试通过过程内存地址反查符号名的方案:这类方案需要调用操作系统/调试器相关的底层API,实现复杂度极高,跨平台、跨编译选项(比如开启优化后符号表可能被剥离)兼容性极差,完全没有必要。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:18:15