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

Fortran中传递未出现的假定形状数组可选哑元作为其他过程的可选实参是否合规?——基于示例与标准条款的疑问

Fortran:未出现的可选假定形状数组能否作为另一过程可选哑元的实参?

通用问题结论

先给你一个明确的答案:从Fortran标准的角度,这种操作是被允许的,但部分编译器的安全检测工具(比如UBSan)会因为底层实现的原因触发报错,这属于工具的额外防护,而非标准禁止的行为。

你的具体示例分析

先看你提供的测试代码:

program main
implicit none
real :: x = 5.0
call test_wrapper(x)
contains
subroutine test_wrapper(x, y)
implicit none
real, intent(in) :: x
real, dimension(:), intent(out), optional :: y
call test(x, y)
end subroutine test_wrapper
subroutine test(x, y)
implicit none
real, intent(in) :: x
real, dimension(:), intent(out), optional :: y
if (present(y)) then
y = x
end if
end subroutine test
end program

你提到UBSan只在y是假定形状数组(dimension(:))时报错,其他类型(固定大小数组、带尺寸参数的数组、可分配数组、指针数组、标量)都没问题——这其实和假定形状数组的底层实现有关。

结合Fortran标准条款拆解

根据Fortran标准第15.5.2.12节(“参数存在性及对未出现参数的限制”)的规定:

未出现的可选哑元需遵守以下限制:
若为数据对象,则不得被引用或定义;若为具有默认初始化的类型,其初始化无效。
[...]以该哑元为基对象且包含一个或多个子对象选择符的指示符不得作为实参传递。[...]若为指针,则不得被分配、释放、置空、指针赋值,或作为对应可选非指针哑元的实参传递。若为可分配对象,则不得被分配、释放,或作为对应可选非可分配哑元的实参传递。[...]除上述列表中注明的情况外,它可作为对应可选哑元的实参传递,此时该哑元也被视为未出现。

对照你的场景:

  • 未出现的y是假定形状数组(非指针、非可分配),传递给的是同类型的可选哑元,完全不属于标准里列出的任何禁止情形。
  • 标准明确说了“除上述列表中注明的情况外,它可作为对应可选哑元的实参传递”,所以这个操作在标准层面是完全合规的。

为什么UBSan会报假定形状数组的错?

这是因为假定形状数组需要依赖隐藏的“描述向量(dope vector)”来存储数组的边界信息,当可选哑元未出现时,这个描述向量可能处于未初始化的状态。UBSan作为内存安全检测工具,会把这种未初始化的内存访问标记为未定义行为,但这是编译器的额外安全检查,并非Fortran标准强制要求的禁止操作。

总结

  • 标准层面:允许将未出现的可选假定形状数组作为同类型可选哑元的实参。
  • 工具层面:UBSan的报错是针对假定形状数组底层实现的安全警示,其他数组类型因为实现方式不同,不会触发这个检测。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:02:51