【问题标题】:Check if array is allocatable in fortran检查数组是否可在 fortran 中分配
【发布时间】:2017-08-27 15:27:01
【问题描述】:

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

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

但是,是否也可以通过某种方式检查一个常规数组是否被声明为 allocatable?以下代码

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)

或许还有其他查询数组性质的语句或方法存在?

【问题讨论】:

  • 在标准 Fortran 中无法做到这一点。也许如果您解释为什么要检查不可分配实体的分配状态,也许有人可以找到解决该问题的巧妙方法。
  • Fortran 是一种静态语言,因为编译器知道变量是固定数组还是可分配数组。但是 Fortran 没有反映程序本身在哪里可以使用此信息(例如,与 C# 不同)。

标签: arrays fortran intel-fortran allocatable-array


【解决方案1】:

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

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

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

this forum thread:

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

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

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


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


最后,当您在此问题中标记英特尔时,我将指向您Intel compiler reference on the matter,您可以在其中看到:

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

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

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

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

如果描述符是由编译器构建的,则用户不能修改它。更改现有描述符的字段是非法的。

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

字节 0 到 3 包含基地址。

(...)

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

bit 1 (0x01): array is defined -- 如果数组已经定义(存储分配),则设置。

(...)

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

保留其他位。

【讨论】:

    猜你喜欢
    • 2015-05-26
    • 2012-01-10
    • 2019-05-17
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 2015-08-03
    • 2014-05-30
    • 2014-04-05
    相关资源
    最近更新 更多