未指定 `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= 时,程序已经进入错误终止流程,后续代码不会继续使用它。
备注:内容仅供参考。
