1

ここでのFortran初心者は、Salford / Silverfrostコンパイラー(元の開発者が亡くなりました)を使用して、Fortran77で記述された古いFortranコードベースで作業するように依頼されました。

元の開発者は、名前付きCOMMONブロックを広範囲に使用し(グローバル変数、AFAIUをエミュレートするため)EQUIVALENCE、次のコードスニペットのように必要に応じてブロックを(再)初期化するために使用します。

      IMPLICIT REAL*8 (A-H,O-Z)

      COMMON/COMMF2D/
     * ASCN(0:99,0:20,0:4)   
     *,FEMPTY2(8700)

      DIMENSION KLCKF2D(38400)
      EQUIVALENCE (KLCKF2D,ASCN)

      DO I= 1,38400                                              
      KLCKF2D(I)= 0
      END DO

これは許容できるプログラミング手法ですか、それとも単なるハックですか?また、コードをGFortranに移植しようとしているので、移植可能ですか?(のような宣言REAL*8はコンパイラへの単なるヒントであり、保証されていないことを理解しています)

4

2 に答える 2

9

EQUIVALENCE何もしませんそれは確かに何も初期化しません、それEQUIVALENCEは定義または宣言です。最近(そして、常に力が増しているFortran 90標準の公開以来)EQUIVALENCEはハックであり、可能な限り避ける必要があります。

このステートメントは、2つの変数がストレージ(Fortran標準ではstorage-associationと呼ばれるもの)を共有することを宣言しています。これの解釈の1つは、同等の名前は単なるエイリアスであるということですが、ステートメントの(乱用)使用により、プログラマーは21世紀のプロのソフトウェアエンジニアによって危険と見なされる他のいくつかのことを行うことができます。

たとえば、これは投稿したスニペットに適用され、EQUIVALENCEさまざまなタイプの変数が同じストレージを共有するために使用できます。と呼ばれる配列があり、ASCNこれは(暗黙的に)とREAL*8呼ばれる配列と同等の型であり、と呼ばれる配列KLCKF2Dは(再び暗黙的に)型INTEGERです。これが意味するのは、ある名前でストレージを参照する場合、ビットパターンはsとして解釈されREAL、別の名前を使用するとsであるということです。また、値を持つ実数のビットパターンは(もちろん)そうではないINTEGERことに注意してください。100.0整数として解釈され100ます。

そして、ハッカーはそれだけではありません。ブロック宣言の効果の1つCOMMONは、変数をメモリに配置することです。この場合、の10500 (= 100*21*5)要素の後にはの要素ASCNが続きます。少し乗算と加算を行うと、このプログラムのデフォルトの整数サイズが4バイト、つまり他の変数で使用されているsの半分のサイズと一致することがわかります。したがって、配列はより大きくなりますが、元のプログラマーは次のバイトがによって占有されることを知っていました。8700FEMPTY238400 = 2*(10500+8700)REAL*8KLCKF2DASCN17400FEMPTY2

そうです、これはプログラムのメモリ内データのその部分のすべてのビットをに設定する方法かもしれませんが、0それは(現在は)恐ろしいハックです。しかし、それは移植可能でなければなりません-後続のFortran標準は、言語とコンパイラー作成者から廃止された機能を削除することについて非常に保守的でした。したがって、下位互換性はFortranプログラマーにとって非常に重要です。

ああ、そしてあなたの質問に答えるために、はいCOMMONブロックは(過去形に注意してください)グローバル変数を宣言して使用するFORTRAN77の方法でした。最近の言語では、変数をaでラップしてMODULE関連付けることにより、変数をグローバルに共有するように宣言するという、はるかに安全なオプションが提供されUSEています。

私は次のような行を見て驚かなかったでしょう

COMMON/COMMF2D/KLCKF2D(38400)

コードでは、COMMONブロックを(ab-)使用して、ストレージの場所の名前を変更したり、再入力したりすることもできます。

私があなたの古いコードにキックを与えている間、暗黙のタイピングも最近では眉をひそめています。すべての宣言を明示的にタイプする方がはるかに良いです。

于 2012-08-08T15:21:27.603 に答える
0

まあ、ポータブルであろうとなかろうと、慣習は...一般的でした。(地球のユーモア。Ork。Ork。)例を挙げましょう。私が再生したゲームZorkのソースコードのデータは、事実上、一般的なブロックと同等のものにすぎません。https://github.com/LydiaMarieWilliamson/zork-fortran

隣接するCの翻訳では、Cでどのように再生されるかがわかります。f2cトランスレーターは、同等性と共通のブロックを処理するのが困難です(私の翻訳ログに表示されます)。私のアドバイスは、すべてをCまたはC ++に再コーディングし、そこで修正することです。これにより、さまざまなプログラマーがアクセスしやすくなります。LAPACKディストリビューション全体(すでにお気づきかもしれませんが)でそれを行う準備をしています-これは約500000から1000000行です。

構造自体に相当するCは、多次元配列を設定するための最良の方法でもあります。全体に1つのベースセグメントのみを割り当てます。次に、2番目の次元に対して、ポインターのセグメント(ラスター)をその次元に割り当てます。次に、3番目の次元では、ポインターのセグメントをその...などに割り当てます。

同等性ステートメント自体には、適切なC同等性はありません。(地球のユーモア。Ork。Ork。)代わりに、同等の同等物は、参照型を使用するC++で最もよく見つかります。C ++では、添字自体([]と()の両方の型括弧を使用)はプログラム可能な演算子であるため、Fortranの添え字をより直接的にレンダリングすることもできます。したがって、上記の割り当てを必要とせずに、等価構造とそのインデックス付けメソッドを静的構造としてそのまま直接変換できます。

于 2021-10-07T22:12:30.423 に答える