2

ifortコンパイラーからibmxlfコンパイラーにコードを移植しようとしています。これは、redhatのifortでうまく機能しますが、AIXシステムのxlfで「NaNQ」が含まれる結果が得られます。コードに配列の境界の読み取りがあると、この問題が発生します。簡単な例を次に示します。

program main                                                                                                                                                    
implicit none                                                                                                                                                   
real(8)::a(1,0:10)=0.D0                                                                                                                                         

print *, a(1,-1)                                                                                                                                                
end program main 

両方のコンパイラを使用すると、間違いや警告なしに正常にコンパイルできます。ifortで私は結果を得る:

0.000000000000000E+000

しかし、xlfでは、次のようになります。

0.247032822920623272E-322

ただし、境界の彼方をさらに読むと、xlfはコンパイルされませんが、ifortは正常にコンパイルされます。

program main                                                                                                                                                    
implicit none                                                                                                                                                   
real(8)::a(1,0:10)=0.D0                                                                                                                                         

print *, a(1,-3:-1)                                                                                                                                                
end program main

私が得るifortで:

0.000000000000000E+000  0.000000000000000E+000  0.000000000000000E+000

xlfではコンパイルされません:

"1.f90", line 5.9: 1516-023 (S) Subscript is out of bounds.
** main   === End of Compilation 1 ===
1501-511  Compilation failed for file 1.f90.

なぜifortとxlfは、この境界を越えた読み取りで異なる解釈をするのですか?コンパイラに厳密にチェックさせ、境界を越えた読み取りが発生しないようにする方法はありますか?結局のところ、私たちのグループはこのコードを15年以上使用していて、ifortに問題がないため、コードでこのバグを見つけるのに長い時間がかかりました。ありがとう。

4

1 に答える 1

4

ほとんどのFortranコンパイラには、実行時に配列境界エラーをチェックするオプションがあります。インデックスが一定のこれらの例では、コンパイル時にエラーが見つかります。一部のコンパイラはデフォルト以外のオプションを使用せずにエラーを検出しますが、他のコンパイラは検出しません。ifortでは、-check boundsを使用して、配列境界チェックを要求します。-checkallを使用して追加のチェックを取得できます。実行時間のコストがかかるため、これらのオプションは通常、デフォルトではありません。しかし、間違った答えを得るコストははるかに高くなる可能性があります!! ランタイムコストが驚くほど低いことがよくあるので、コード開発中、およびランタイムコストが許容できる場合は本番環境でもランタイムチェックを使用することをお勧めします。

于 2012-11-09T18:26:54.953 に答える