伊恩布什的回答正确地指出问题中的使用是不允许的。不过,我们可以更精确。(括号中引用了 Fortran 2018 标准。)
在三种情况下,可以使用未分配的可分配实际参数:
- 当虚拟参数也是可分配的(仅自 Fortran 2003 或 Fortran 95+TR-15581 起)(15.5.2.6 p.2)
- 当虚拟参数是可选的普通参数时(仅自 Fortran 2008 起)(15.5.2.12 p.1、15.5.2.4 p.7)
- 当过程是内在查询功能时(15.5.2.4 p.7、16.1 p.2)
“未使用”的虚拟参数也不例外。无论可分配参数是数组还是标量,这些限制都适用。
任何其他用途意味着程序不符合标准(15.5.2.4 p.7、15.5.2.7 p.2)。
在符合标准的程序中,这些可接受的情况中的每一个都有一个可用的显式接口。可分配或可选的虚拟参数需要一个 (15.4.2.2 p.1(3)),并且可访问的内部过程始终具有可用的显式接口 (15.4.2.1 p.1)。
这些对程序的要求并不是编译器必须能够分析的。这样一个不符合标准的程序并不一定意味着你在编译和运行的时候会看到问题。在问题程序的情况下,它不会试图以不好的方式取消引用,你很可能会侥幸逃脱。但是,编写不符合标准的程序并不好,依赖它们“工作”非常糟糕。
有一些事情可能会出错:
- 运行时检查
- 编译时检查
value
具有属性的假人(同样,在这种情况下需要显式接口)
也就是说,您的程序在某些编译器/编译器选项下的行为可能会有所不同。如果你的编译器注意到你应该有一个可用的显式接口,它可能会拒绝编译程序。如果运行时检查参数是否已分配,程序可能会在进入子例程时中止。value
如果在未分配实际参数的情况下尝试使用属性创建数组的匿名可定义副本,运行时可能会做一些非常意外的事情。
对于这个问题,还有另一个不合规需要担心。显式长度伪参数foo(n)
意味着实际参数必须至少有n
元素。未分配的数组至少没有n
元素(对于任何元素,甚至为零n
)。如果foo
是intent(out)
编译器将在其权利范围内做一些事情来“取消定义”实际参数的这些元素。这可能会失败。