1

ルーチンを含む FORTRAN コードがあります。

SUBROUTINE READ_NC_VALS(NCID, RECID, VARNAME, VARDATA)
integer ncid, recid
character*(*) varname
real*8 vardata
dimension vardata(15,45,75)

etc.

このコードに柔軟性を追加したいので、最初にオプションのフラグ引数を追加することでそれを行うと考えました。

SUBROUTINE READ_NC_VALS(NCID, RECID, VARNAME, VARDATA, how_to_calculate)

! everything the same and then ...
logical, optional :: how_to_calculate

さて、この時点では、「how_to_calculate」も使用していません。テスト用にコードに入れているだけです。だから私は滞りなくコードをコンパイルします。それを実行すると、サブルーチンでエラーが発生します。具体的には、後でコード内の値の一部が、そのオプションの引数がない場合の値から「魔法のように」変更されます。新しい値はコードのロジックにとって意味をなさないため、丁寧にエラー メッセージを表示して終了します。この時点では、このオプションを使用していないことをもう一度強調します口論。そこで、思い立って、このルーチンを呼び出すソース内のすべての場所に戻り、新しい引数をオプションにしましたが、すべての呼び出しでその値を入力しました。これを行うと、コードは正常に実行されます。元気?サブルーチンに未使用のオプションの引数が存在するだけで、他のデータが破損する可能性はありますか? そして、このオプションの引数に入力パラメーターを追加すると、どうすれば問題を解決できるのでしょうか? ちなみに、これはPGIでコンパイルされています。

何か案は?ありがとう。

ところで、これ以上コードを提供できなくて申し訳ありません。私がそんなことをしたら、上司は私にあまり満足しないかもしれません。私はルールを作りません。私はただここで働いています。

4

2 に答える 2

4

0Fortran のオプション引数は、呼び出しサブルーチンによって値が提供されないオプション引数ごとに (null ポインター) を渡すことによって実装されます。このため、オプションの引数を取るサブルーチンは次のことを行う必要があります。

  • INTERFACE呼び出しサブルーチン内に明示的な定義があるか
  • またはモジュールレベルのサブルーチンであること (それらの場合、インターフェイスは自動的に生成されます)

オプションの引数をサブルーチンに追加しても、それが呼び出し元にインターフェイスを持たないか、モジュール レベルのサブルーチンではない場合、コンパイラは正しい呼び出しシーケンスを生成しません。予想よりも少ない引数を渡します。CHARACTER*(*)これは、PGI がすべての引数の長さを引数リストの最後に渡す Unix システムで問題を引き起こす可能性があります (Windows では、文字列のアドレスの後の次の引数として長さを渡します)。欠落している引数が 1 つあると、スタック内の長さ引数の配置がシフトされ (または x64 では間違ったレジスタに配置され)、VARNAMEによって受信される文字列の長さが正しくなくなりREAD_NC_VALSます。これは、メモリの上書きや、プログラム ロジックに従って変更されるべきではない値の "魔法のような" 変更など、あらゆる種類の不適切な動作につながる可能性があります。

于 2012-07-10T11:53:08.687 に答える
1

明らかに、属性の有無にかかわらず、仮引数をサブルーチンに追加するだけでoptional問題が発生することはありません。ただし、この変更により、コードに別の問題が発生する可能性があります。この問題は既に存在していましたが、目に見える悪影響はありませんでした。

これ以上コードがなければ、推測するしかありませんが、これは通常あまり役に立ちません。オプションの引数を使用する場合、明示的なインターフェイスが必要であることが頭に浮かびます。コードはモジュールに編成されていますか?

于 2012-07-09T22:47:49.007 に答える