PAYATHON 2026

未指定 `stat` 时,`allocate` 失败会如何处理?

排障赵师傅

未指定 stat= 时,allocate 一旦发生分配错误,就会启动错误终止(error termination),不会带着未分配的 a 继续执行后续语句。

如果分配失败后只需要终止程序,可以直接写:

allocate(a(n))

为什么可以省略检查

J3 的 Fortran 2018 工作文档第 9.7.1.2 节规定:执行不含 STAT= 的 ALLOCATE 语句时,如果发生错误条件,就启动错误终止。

两种写法的区别是:

  • 不指定 stat=:分配错误直接触发错误终止。
  • 指定 stat=:状态变量在成功时为 0,失败时为非零值,程序可以继续执行,自行处理错误。Intel 的 ALLOCATE 文档也说明了这一行为。

指定了 stat=,就需要检查它的值,因为分配失败后如何执行,要由程序自行决定。

需要自定义错误信息时怎么写

即使不打算在失败后恢复执行,也可以保留 stat=,以便输出数组名称、申请规模等上下文。加上 errmsg=,还可以取得运行时提供的错误说明:

program allocation_example
    use, intrinsic :: iso_fortran_env, only: error_unit
    implicit none

    integer, parameter :: n = 1000
    integer :: stat
    character(len=512) :: errmsg
    real, allocatable :: a(:)

    allocate(a(n), stat=stat, errmsg=errmsg)

    if (stat /= 0) then
        write(error_unit, *) "Allocation failed: a, n =", n
        write(error_unit, *) "stat =", stat, trim(errmsg)
        error stop 1
    end if

    a = 0.0
end program allocation_example

应当在错误分支中读取 errmsg;分配成功时,这条语句不会更新它的值。具体的错误码和错误文字取决于实现,不能假定某个固定数值一定表示内存不足。参见第 9.7.4、9.7.5 节。

几个容易混淆的地方

分配错误会触发错误终止,但标准不保证固定的 runtime error 文案、调用栈或退出码。这些诊断细节取决于编译器及其运行时实现。

原代码中的 stop 1 与默认行为也不完全等价。在 Fortran 术语中,STOP 启动正常终止,ERROR STOP 启动错误终止,数字 1 不会改变这个分类。因此,上面的示例使用 error stop 1。参见第 11.4 节。

unallocated 描述分配状态,undefined 描述值的定义状态。如果 a 原先未分配,此次也未成功分配,它的分配状态仍是未分配。省略 stat= 时,程序已经进入错误终止流程,后续代码不会继续使用它。

备注:内容仅供参考。