fortran - 是否允许为另一个过程的可选参数传递一个不存在的假定形状数组?
问题描述
在这个最小的例子中,是否允许传递 的可选虚拟参数可能不是对应的可选虚拟参数的y
实际参数?test_wrapper
present
y
test
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
UndefinedBehaviourSanitizer 报错,说明不是:https ://godbolt.org/z/nKj1h6G9r
在这个 Fortran 标准文档(第 311 页的第 15.5.2.12 节,“参数存在和参数不存在的限制”)中,它说:
- 不存在的可选虚拟参数受以下限制。
- 如果是数据对象,则不应被引用或定义。如果它是具有默认初始化的类型,则初始化无效。
- [...]
- [...]
- [...]
- 不应将其作为基础对象并带有一个或多个子对象选择器的指示符作为实际参数提供。
- [...]
- 如果它是一个指针,则它不应被分配、解除分配、无效化、指针分配或作为对应于可选非指针虚拟参数的实际参数提供。
- 如果它是可分配的,则不应分配、解除分配或作为与可选的不可分配伪参数相对应的实际参数提供。
- [...]
- 除非在上面的列表中注明,它可以作为与可选的虚拟参数相对应的实际参数提供,然后也被认为不存在。
我正在努力阅读该列表中的标准,所以也许其中一个我不完全理解的项目禁止使用假定形状的数组?但在我看来,这些限制都不适用于这种情况。
但有趣的是,UBSan 似乎只在使用 时引发错误dimension(:)
,即如果y
是假设形状的数组。其他任何东西dimension(2)
,如dimension(n)
添加大小参数n
,allocatable
或pointer
什么都没有似乎不会触发 UBSan。
解决方案
没有可选的虚拟参数的假设形状的使用没有额外的限制。允许将不存在的假定形状数组参数作为另一个过程中可选虚拟参数的实际参数,除非另一个限制阻止它。(随后的虚拟参数将被视为不存在。)
如前所述,列出的限制均未提及“假定形状”。特别是,您引用的任何内容(如伊恩布什评论)都不适用于这种情况。这使得“除了上面列表中指出的情况外,它可能会被提供......”是允许的。
如果您想进一步检查,y
每个子程序的假定形状参数是一个普通的虚拟变量(并受 15.5.2.4 的规则约束)。
gfortran 7 没有抱怨。这个版本看不懂可能有关系-std=f2018
。
为了完整起见,让我们来看看为什么限制(所有限制,不仅仅是问题中引用的限制)不适用。我不会引用这些限制,所以好奇的人需要查找那些不在问题中的文本。
- 两者都不
y
存在时不被引用或定义(作为实际参数出现不是引用或定义)。 - 两者都没有
y
出现在指针赋值中(也不是指针)。 - 过程或过程指针都不
y
是。 y
oftest_wrapper
不用作非可选虚拟参数的实际参数;y
oftest
不用作实际参数。- 在
test_wrapper
实际参数中是y
它本身,而不是 ; 的子对象y
。y
intest
不用作实际参数。 - 尽管是数组,但两者都不
y
是用于引用基本过程的实际参数。 - 也不
y
是指针。 - 两者都不
y
是可分配的。 - 两者都没有
y
长度类型参数(尤其是没有查询)。 - 两者都不
y
用作选择器。 - 两者都不
y
用于程序指示符。 - 过程组件引用中都没有
y
使用。
下面更简单的程序显示了相同的问题:
program main
implicit none
call test_wrapper
contains
subroutine test_wrapper(y)
real, dimension(1), intent(out), optional :: y
call test(y)
end subroutine test_wrapper
subroutine test(y)
real, dimension(:), intent(out), optional :: y
if (present(y)) y=0 ! Used to silence unrelated warning
end subroutine test
end program
推荐阅读
- angular - 带有参数的自定义 Angular 验证器只运行一次
- authentication - 鱿鱼将每个传出IP绑定到用户?
- node.js - 如何通过 req.body 和 node-cron 安排电子邮件
- python - 如何将参数(从表单)传递给模型方法并返回计算
- django - 如何修复 social_core.exceptions.AuthMissingParameter 错误
- github - 无法将提交从本地分支推送到 github 存储库
- c# - 关闭承载 Windows 窗体控件的 WPF UserControl 的 WinForm 时窗口句柄无效
- python - 返回值最多 5 位小数
- pycharm - Pycharm升级到2019 1.1后,老版本Pycharm的项目打不开。它只是停留在加载项目
- javascript - == 在我的 IF 语句中不起作用