1

编辑:Gfortran 6 现在支持这些扩展 :)

我有一些广泛使用 UNION 和 MAP 的旧 f77 代码。我需要使用不支持这些扩展的 gfortran 编译它。我已经想出了如何转换除这些之外的所有不支持的扩展,我不知所措。我对可能的方法有几个想法,但未能成功实施任何东西。我需要以与当前相同的方式访问现有的 UDT;我可以重新实现 UDT,但它们的接口不能改变。

我所拥有的示例:

TYPE TEST
  UNION
    MAP
      INTEGER*4 test1
      INTEGER*4 test2
    END MAP
    MAP
      INTEGER*8 test3
    END MAP
  END UNION
END TYPE

必须通过以下方式访问元素:TEST%test1、TEST%test2、TEST%test3

到目前为止我的想法:

  1. 以某种方式替换为 fortran EQUIVALENCE。
  2. 在 C/C++ 中定义结构并以某种方式使它们对 FORTRAN 代码可见(怀疑这是可能的)

我想当 UNION 和 MAP 被排除在标准之外时,f77 到 f90/95 一定有很多重构。如果有/被处理过怎么办?

编辑:接受的答案有一个允许内存重叠的解决方法,但就保留 API 而言,这是不可能的。

4

3 回答 3

3

UNION 和 MAP 从来都不是任何 FORTRAN 标准的一部分,它们是供应商扩展。(参见,例如, http: //fortranwiki.org/fortran/show/Modernizing+Old+Fortran)。所以它们并没有真正被排除在 Fortran 90/95 标准之外。它们导致变量在内存中重叠。如果代码确实使用了这个特性,那么你将需要使用equivalence. 在不进行转换的情况下在不同类型的变量之间移动数据的首选方法是transfer内在方法,但对您而言,您必须确定需要转换的每个地方,而使用equivalence它正在隐含地发生。当然,这会使代码更难理解。如果内存覆盖只是为了节省空间并且不使用变量的等价性,那么您可以摆脱这个“功能”。如果代码像您的示例一样,带有小整数,那么我猜想正在使用内存覆盖。如果覆盖是大型数组,则可能是为了节省内存。如果这些声明还创建了新类型,您可以使用用户定义类型,这绝对是 Fortran >=90 的一部分。

如果代码使用不同类型变量的内存等效,这可能是不可移植的,例如,整数和实数的内部表示可能在最初运行此代码的机器和当前机器之间不同。或者这些变量可能只是用于存储位。有很多事情要弄清楚。

PS针对评论中的问题,这里是一个代码示例。但是......要清楚......我不认为使用等价是好的编码实践。使用我通常与 gfortran 一起使用来调试代码的编译器选项,gfortran 拒绝此代码。使用更宽松的选项,gfortran 将编译它。ifort 也会如此。

module my_types

use ISO_FORTRAN_ENV

type test_p1_type
    sequence
    integer (int32) :: int1
    integer (int32) :: int2
end type test_p1_type

type test_p2_type
   sequence
   integer (int64) :: int3
end type test_p2_type

end module my_types


program test

use my_types

type (test_p1_type) :: test_p1
type (test_p2_type) :: test_p2

equivalence (test_p1, test_p2)

test_p1 % int1 = 2
test_p1 % int1 = 4

write (*, *) test_p1 % int1, test_p1 % int2, test_p2 % int3

end program test
于 2013-02-06T16:43:21.680 回答
1

问题是联合是用于节省空间还是用于相同数据的替代表示。如果您正在移植,请查看它是如何使用的。也许,因为篇幅有限,它是以必须共享变量的方式编写的。现在有了更多的内存,也许这不是必需的,也可能不需要联合。在这种情况下,它只是两种不同的类型

于 2013-02-09T11:30:46.507 回答
1

对于那些只想用这些扩展编译代码的人:Gfortran 现在在版本 6 中支持 UNION、MAP 和 STRUCTURE。https://gcc.gnu.org/bugzilla/show_bug.cgi?id= 56226

于 2016-08-16T09:36:57.270 回答