1

allocated在 fortran 中,可以使用以下语句检查是否分配了可分配数组:

program test_allocated
  integer :: i = 4
  real(4), allocatable :: x(:)

  print *, 'before allocation of x'
  print *, 'allocated(x)'
  print *, allocated(x)

  allocate(x(i))
  print *, 'after allocation of x'
  print *, 'allocated(x)'
  print *, allocated(x)

end program test_allocated

但是,是否也可以以某种方式检查常规数组是否被声明为可分配的?以下代码

program test_allocated
  integer :: i = 4
  real(4), allocatable :: x(:)
  real(4)::y
  print *, 'before allocation of x'
  print *, 'allocated(x)'
  print *, allocated(x)
  print *, 'allocated(y)'
  print *, allocated(y)
  allocate(x(i))
  print *, 'after allocation of x'
  print *, 'allocated(x)'
  print *, allocated(x)
  print *, 'allocated(y)'
  print *, allocated(y)
end program test_allocated

抛出错误

D:\TEMP\FortranTest\ifort>ifort test.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Inte
l(R) 64, Version 13.0.1.119 Build 20121008
Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.

test.f90(9): error #6547: The ARRAY argument of the ALLOCATED inquiry intrinsic
function shall be an allocatable array.   [Y]
  print *, allocated(y)
---------------------^
test.f90(15): error #6547: The ARRAY argument of the ALLOCATED inquiry intrinsic
 function shall be an allocatable array.   [Y]
  print *, allocated(y)
---------------------^
compilation aborted for test.f90 (code 1)

也许存在另一种查询数组性质的语句或方法?

4

1 回答 1

1

一些编译器将数组的元数据存储在 dope 数组描述符中,包括可分配性、连续性、元素存储大小、定义状态等属性,如果它是指针……语言在内部需要它们来检查特定过程调用的接口匹配。

因此,检查这种元信息在技术上是可行的,但这样做也几乎没有用处。同样,Fortran 是静态类型的,编译器能够在编译时进行所有这些检查。

此外,该语言的设计方式是,当您明确声明它是可分配的(或指针)时,您只能处理变量(或虚拟参数)的分配。在所有其他情况下,您可以使用数组而不用担心它是如何分配的。

请参阅此论坛主题

一旦你分配了一个可分配数组,它现在是一个和其他数组一样“好”的数组,它可以作为实际参数传递给甚至不需要知道它是可分配的过程(或 C 函数)。我可能会补充说,这同样适用于指针数组,尽管对这种情况有一点警告(涉及指针数组可能指向非连续切片的可能性)。

对于您的特定情况,您正在尝试将内部函数allocated与不可分配的数组一起使用y,从而给出错误。在对数组使用此函数之前,您无需检查数组是否可分配,您只需要知道,如果您没有明确将其声明为allocatable(就像您对 所做的那样x),则它不是.

同样,如果要在函数或子例程中管理变量的分配,只需将虚拟参数声明为可分配的,并且保证只有可分配的变量会被过程接受(与指针相同)。


如果您有充分的理由去探究变量的内部表示并且您知道自己在做什么,那么您可以参考@VladmirF 关于其他问题的答案,或者深入了解您的特定编译器的参考手册。此外,该标准的最新版本指定了一个标准化的数组描述符,旨在与 c 代码进行互操作。


最后,当您在此问题中标记英特尔时,我将向您指出有关此事的英特尔编译器参考,您可以在其中看到:

使用数组描述符的缺点是它会增加出错的机会。此外,相应的代码是不可移植的。具体来说:

如果描述符定义不正确,程序可能会访问错误的内存地址,从而可能导致一般保护错误。

数组描述符格式特定于每个 Fortran 编译器。使用数组描述符的代码不能移植到其他编译器或平台。

数组描述符格式将来可能会改变。

如果描述符是由编译器构建的,则用户无法对其进行修改。更改现有描述符的字段是非法的。

当前英特尔® Fortran 阵列描述符在使用 IA-32 架构的系统上的组件如下:

字节 0 到 3 包含基地址。

(...)

字节 12 到 15 包含一组标志,用于存储有关数组的信息。这包括:

位 1 (0x01):数组已定义——如果数组已定义(已分配存储)则设置。

(...)

位 8 (0x80):如果指向的数组是 ALLOCATABLE 则设置。

其他位被保留。

于 2018-10-19T19:39:35.863 回答