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を参照してください)。したがって、それらは実際にはFortran90/95標準から除外されていませんでした。それらは変数をメモリ内でオーバーラップさせます。コードが実際にこの機能を使用している場合は、を使用する必要がありますequivalence。変換せずに異なるタイプの変数間でデータを移動するための好ましい方法はtransfer本質的なものですが、変換が必要なすべての場所を特定する必要があります。equivalenceそれは暗黙のうちに起こっています。もちろん、それはコードを理解しにくくします。メモリオーバーレイがスペースを節約するためだけのものであり、変数の同等性が使用されていない場合は、この「機能」を取り除くことができます。コードがあなたの例のようで、整数が小さい場合は、メモリオーバーレイが使用されていると思います。オーバーレイが大きな配列の場合は、メモリを節約するために行われた可能性があります。これらの宣言が新しい型も作成している場合は、ユーザー定義の型を使用できます。これは間違いなくFortran>=90の一部です。

コードが異なるタイプの変数のメモリ等価を使用している場合、これは移植性がない可能性があります。たとえば、整数と実数の内部表現は、このコードが最初に実行されたマシンと現在のマシンで異なる可能性があります。あるいは、変数はビットを格納するために使用されているだけかもしれません。理解することがたくさんあります。

PSコメントの質問に答えて、ここにコードサンプルがあります。しかし....明確にするために...私は同等性を使用することは良いコーディング慣行であるとは思いません。コードをデバッグするためにgfortranで通常使用するコンパイラオプションを使用すると、gfortranはこのコードを拒否します。より緩いオプションを使用すると、gfortranはそれをコンパイルします。だから努力します。

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

これらの拡張機能を使用してコードをコンパイルしたいだけの場合: Gfortran はバージョン 6 で UNION、MAP、および STRUCTURE をサポートするようになりました。https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56226

于 2016-08-16T09:36:57.270 に答える
1

問題は、ユニオンがスペースを節約するために使用されたのか、それとも同じデータの代替表現を持つために使用されたのかです。移植する場合は、それがどのように使用されているかを確認してください。スペースが限られているため、変数を共有する必要があるように記述されている可能性があります。メモリが大容量化された現在では、これは必要ないかもしれませんし、union は必要ないかもしれません。その場合、それはちょうど2つの別々のタイプです

于 2013-02-09T11:30:46.507 に答える