2

古い FORTRAN 77 プログラムを使用していて、奇妙なバグに遭遇しました。現状では、コードは正常に実行されているように見え、1 秒もかからずに終了します。しかし、それは私が興味のない無関係な出力を大量に生成します。そのため、ソースを調べて、余分な WRITE ステートメントをすべてコメントアウトしました。

いくつかの WRITE ステートメントをコメント アウトすると、コードの実行が少し遅くなるように見えます (それについてはよくわかりませんが、忙しくするためにスクロールするテキストの行数が少ないため、遅く見えるだけかもしれません)。 . そして、余分な WRITE ステートメントの最後の部分をコメント アウトすると、プログラムがハングするだけで、実行が終了しません。

さて、論理的には、WRITE ステートメントをコメントアウトしても、プログラムの残りの部分は完全に機能するはずですよね? これは、コードのどこかに別の問題が潜んでいて、WRITE ステートメントが何らかの形でそれを隠していることを意味していると思います (バッファをクリアしているのでしょうか?)。

Fortran を知っている同僚 (数少ない同僚の 1 人) は、私が文ラベルをうっかりコメントアウトしたのではないかと示唆しましたが、そうではありません。Fortran を知らないが、一般的なプログラミングに非常に熟練している別の同僚は、ポインターの問題のように聞こえると示唆しましたが、私が知る限り、範囲外のインデックスを関数に渡したことはありません。配列であり、このような問題が他にどのように発生するかはわかりません。

PowerPC Mac コンピュータで g77 を使用してプログラムをコンパイルしています。

4

2 に答える 2

4

これは鈍感に聞こえるかもしれませんが、失礼かもしれませんが...

標準的な回答番号 1 がここに適用されます。問題を理解していれば、助けを求めることはありません。まともな助けが得られる可能性が少しでも欲しいなら、問題だと思うものの解釈ではなく、実際の問題を示す必要があります。デバッグするコードではないものや、問題の原因でさえないものを見て、コードをデバッグすることはできません。

だから、コードを見せてください!
- 宣言は非常に重要
です - どのようにコンパイルし、どのオプションをオンにしますか?
- 配列境界の外へのステップアウトは、コンパイラがコンパイル時にキャッチする必要があるものです
- 画面または他のユニット (ファイル) に書き出す write ステートメントです。後で何かが読み取られる可能性はありますか?
- 保存および初期化された値に問題がある可能性がありますか? (ここは推測です)

あなたはプログラムが「ハングする」と言った。ハングするコードの部分を特定しようとしましたか? (無限ループ)、またはある種の長いループに入っただけですか?

「印刷ステートメントのコメント」エラーを数回見たことがあります (実際には最後に発生したのはごく最近のことです)。ですから、ゆっくりとやってみてください...まず、エラーが消えない原因とならないプログラムの部分を追い出して、そこから作業を始めてください。

提供された情報から言えることは本当に何もありません、申し訳ありません。

編集: @bambeck - 私は g77 (または powerMac) を持っていないので、正確な指示を与えることはできません (したがって、私のあいまいさです)。ヘルプなどでそれらのリストが表示されるはずです)。すべての警告を表示するように有効にします (そのように表現する必要があります)、コンパイル時の配列境界チェックなど...それが何か興味深いものを生成する場合は、投稿してください。

それに関する限り、あなたが示した書き込みステートメント自体には何も問題はありません。

ループが本当に無限かどうかもわかりませんが、30 分以上かかります。保存については少し有望に見えますが... 精巧ですか?

ああ、ふと思いついたことがあります。スタンダードがそれについて何を言っているのかわからないので、横でそれについて言及しました。配列が(何らかの値に)適切に初期化されていない場合、配列をゼロ値に設定するコンパイラもあれば、内容が保存されている場所のメモリからランダムに何かを選択するコンパイラもあります。かつて似たような問題が発生し、奇妙な結果が得られたので、それを思い出しました。あなたが同じ問題を抱えているとは言いません。このような場合に SAVE ステートメントを実行すると、奇妙な動作が発生する可能性があります。

結果 (プログラムが「機能する」とき) は、異なる実行 (同じ入力データを使用) で異なることがありますか?

于 2011-08-11T05:19:51.173 に答える
0

1)一般に関数を書くことができます:write(*、*)f(x)ここで、関数f()は(xの変更を含む)あらゆることを実行するため、writeステートメントにコメントを付けるとプログラムが実際に変更されます。悪い練習ですが、可能です。

2)範囲外の配列にアクセスするなど、まったく関係のないバグが発生する可能性があります。コードに何らかの変更を加えると、コンパイラがメモリ内の変数を異なる方法で整列させる可能性があるため、「非表示」のバグが発生して問題が発生する可能性があります。(配列境界チェックをオンにし、初期化されていない変数にアクセスするかどうかをチェックすることをお勧めします)

于 2011-09-16T17:19:34.347 に答える