Convert FORTRAN DEC UNION/MAP extensions to anything else

陌路散爱 提交于 2020-01-05 05:28:07

问题


Edit: Gfortran 6 now supports these extensions :)

I have some old f77 code that extensively uses UNIONs and MAPs. I need to compile this using gfortran, which does not support these extensions. I have figured out how to convert all non-supported extensions except for these and I am at a loss. I have had several thoughts on possible approaches, but haven't been able to successfully implement anything. I need for the existing UDTs to be accessed in the same way that they currently are; I can reimplement the UDTs but their interfaces must not change.

Example of what I have:

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

Access to the elements has to be available in the following manners: TEST%test1, TEST%test2, TEST%test3

My thoughts thusfar:

  1. Replace somehow with fortran EQUIVALENCE.
  2. Define the structs in C/C++ and somehow make them visible to the FORTRAN code (doubt that this is possible)

I imagine that there must have been lots of refactoring of f77 to f90/95 when the UNION and MAP were excluded from the standard. How if at all was/is this handled?

EDIT: The accepted answer has a workaround to allow memory overlap, but as far as preserving the API, it is not possible.


回答1:


UNION and MAP were never part of any FORTRAN standard, they are vendor extensions. (See, e.g., http://fortranwiki.org/fortran/show/Modernizing+Old+Fortran). So they weren't really excluded from the Fortran 90/95 standard. They cause variables to overlap in memory. If the code actually uses this feature, then you will need to use equivalence. The preferred way to move data between variables of different types without conversion is the transfer intrinsic, but to you that you would have to identify every place where a conversion is necessary, while with equivalence it is taking place implicitly. Of course, that makes the code less understandable. If the memory overlays are just to save space and the equivalence of the variables is not used, then you could get rid of this "feature". If the code is like your example, with small integers, then I'd guess that the memory overlay is being used. If the overlays are large arrays, it might have been done to conserve memory. If these declarations were also creating new types, you could use user defined types, which are definitely part of Fortran >=90.

If the code is using memory equivalence of variables of different types, this might not be portable, e.g., the internal representation of integers and reals are probably different between the machine on which this code originally ran and the current machine. Or perhaps the variables are just being used to store bits. There is a lot to figure out.

P.S. In response to the question in the comment, here is a code sample. But .... to be clear ... I do not think that using equivalence is good coding pratice. With the compiler options that I normally use with gfortran to debug code, gfortran rejects this code. With looser options, gfortran will compile it. So will 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



回答2:


The question is whether the union was used to save space or to have alternative representations of the same data. If you are porting, see how it is used. Maybe, because the space was limited, it was written in a way where the variables had to be shared. Nowadays with larger amounts of memory, maybe this is not necessary and the union may not be required. In which case, it is just two separate types




回答3:


For those just wanting to compile the code with these extensions: Gfortran now supports UNION, MAP and STRUCTURE in version 6. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56226



来源:https://stackoverflow.com/questions/14733238/convert-fortran-dec-union-map-extensions-to-anything-else

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!