関連情報
ホーム > 製品 & サービス > NAG Fortran コンパイラ > 実行時エラーをチェックする

NAG Fortran コンパイラ(Fortran Builder)で
実行時エラーをチェックする

NAG Fortran コンパイラ(Fortran Builder)では、コンパイラオプション -C=... を付けることによって、実行時のエラーチェックを強化することができます。

具体的には、以下の項目をチェックすることができます。

  • -C=array
: 配列の範囲
  • -C=bits
: ビット組込み関数の引数
  • -C=calls
: 手続の参照
  • -C=dangling
: ダングリングポインタ
  • -C=do
: 増分値 0 の DO ループ
  • -C=intovf
: 整数オーバーフロー
  • -C=present
: OPTIONAL 引数の参照
  • -C=pointer
: ポインタの参照
  • -C=recursion
: 不正な再帰
  • -C=undefined
: 未定義の変数
  • -C=all
: -C=undefined を除くすべてのチェックを行います。
  • -C
: -C=undefined, -C=dangling, -C=intovf を除くすべてのチェックを行います。

詳細は「NAG Fortran Compiler, Release 6.1 マニュアル - 2.4 コンパイラオプション」をご参照ください。

※ Fortran Builder では、プロジェクトの設定の「Fortran コンパイラ > 実行時診断」から、上記のコンパイラオプションを有効/無効にすることができます。

以下、各チェック項目に対してプログラム例を示します。

配列の範囲

[ rtc_array.f90 ]

program main
  implicit none
  integer i, x(3)
  x = 999
  do i = 1, 5
    print *, x(i) ! 配列の範囲外 x(4), x(5) を参照している。
  end do
end program

このプログラムを実行すると、例えば、

 999
 999
 999
 1
 37879340

コンパイラオプション -C=array(または -C, -C=all)を付加すれば、

実行時エラー: rtc_array.f90, line 6: Xの第1添字(値 4)が範囲外です(1:3)
致命的なエラーでプログラムが終了しました

ビット組込み関数の引数

[ rtc_bits.f90 ]

program main
  implicit none
  integer i
  do i = 1, 32
    print *, ibset(0, i) ! 第2引数がビット範囲を超えている。
  end do
end program

このプログラムを実行すると、例えば、

 2
 4
 8
 16
 ...
 
 536870912
 1073741824
 -2147483648
 1

コンパイラオプション -C=bits(または -C, -C=all)を付加すれば、

実行時エラー: rtc_bits.f90, line 5: 組込みIBSETのPOS引数(32)が範囲外です(0:31)
致命的なエラーでプログラムが終了しました

手続の参照

[ rtc_calls_sub.f90 ]

subroutine add_print(a, b)
  implicit none
  real, intent(in) :: a, b
  print *, a + b
end subroutine

[ rtc_calls_main.f90 ]

program main
  implicit none
  integer :: a = 2, b = 3
  call add_print(a, b) ! 実数の仮引数に整数の実引数を渡している。
end program

このプログラムを実行すると、例えば、

   7.0064923E-45

コンパイラオプション -C=calls(または -C, -C=all)を付加すれば、

実行時エラー: rtc_calls_sub.f90, line 1: 無効な手続き参照-
仮引数Aの実引数がREAL(real32)ではなくINTEGER(int32)です
致命的なエラーでプログラムが終了しました

ダングリングポインタ

[ rtc_dangling.f90 ]

program main
  implicit none
  integer, pointer :: p(:)
  integer, target, allocatable :: x(:)
  allocate (x(3))
  x = (/ 1, 2, 3 /)
  p => x
  deallocate (x)
  print *, p ! 解放されたメモリ領域を参照している。
end program

このプログラムを実行すると、例えば、

 0 0 3

コンパイラオプション -C=dangling(または -C=all)を付加すれば、

実行時エラー: rtc_dangling.f90, line 9: 遊離した(dangling)ポインタPへの参照が行われました
指示先がrtc_dangling.f90の8行目で解放されています
致命的なエラーでプログラムが終了しました

増分値 0 の DO ループ

[ rtc_do.f90 ]

program main
  implicit none
  integer i, s
  s = 0
  do i = 1, 10, s ! ループの増分値が 0 である。
    print *, i
  end do
end program

このプログラムを実行すると、何も出力されません。

コンパイラオプション -C=do(または -C, -C=all)を付加すれば、

実行時エラー: rtc_do.f90, line 5: DOの増分値がゼロです
致命的なエラーでプログラムが終了しました

整数オーバーフロー

[ rtc_intovf.f90 ]

program main
  implicit none
  integer n
  n = huge(n)
  print *, n + 1 ! 整数の最大値に 1 を加算している。
end program

このプログラムを実行すると、例えば、

 -2147483648

コンパイラオプション -C=intovf(または -C=all)を付加すれば、

実行時エラー: rtc_intovf.f90, line 5: 2147483647+1でINTEGER(int32)オーバーフローが発生しました
致命的なエラーでプログラムが終了しました

OPTIONAL 引数の参照

[ rtc_present.f90 ]

program main
  implicit none
  integer :: a = 2, b = 3
  call add_print(a, b)
contains
  subroutine add_print(a, b, c)
    integer, intent(in) :: a, b
    integer, intent(in), optional :: c
    print *, a + b + c ! 省略された引数 c を参照している。
  end subroutine
end program

このプログラムを実行すると、プログラムがハングアップします。

コンパイラオプション -C=present(または -C, -C=all)を付加すれば、

実行時エラー: rtc_present.f90, line 9: 存在しない省略可能引数Cへの参照が行われました
致命的なエラーでプログラムが終了しました

ポインタの参照

[ rtc_pointer_undef.f90 ]

program main
  implicit none
  real, pointer :: x(:)
  print *, size(x) ! 未定義のポインタを参照している。
end program

このプログラムを実行すると、例えば、

 1254272

コンパイラオプション -C=pointer(または -C, -C=all)を付加すれば、

実行時エラー: rtc_pointer_undef.f90, line 4: 不定ポインタXへの参照が行われました
致命的なエラーでプログラムが終了しました

[ rtc_pointer_null.f90 ]

program main
  implicit none
  real, pointer :: y(:) => null()
  print *, size(y) ! 空状態のポインタを参照している。
end program

このプログラムを実行すると、例えば、

 0

コンパイラオプション -C=pointer(または -C, -C=all)を付加すれば、

実行時エラー:rtc_pointer_null.f90, line 4: 空状態のポインタYへの参照が行われました
致命的なエラーでプログラムが終了しました

不正な再帰

[ rtc_recursion.f90 ]

program main
  implicit none
  call dispatch(p1, 111)
contains
  subroutine dispatch(p, n) ! 再帰的な手続きに RECURSIVE が付いていない。
    interface
      subroutine p
      end subroutine
    end interface
    integer, intent(in) :: n
    integer x(1000, 1000)
    x = n
    print *, 'Hello', x(1, 1)
    call p
    print *, 'Goodbye', x(1, 1)
  end subroutine
  subroutine p1
    call dispatch(p2, 999)
  end subroutine
  subroutine p2
    print *, 'Hello World'
  end subroutine
end program

このプログラムを実行すると、例えば、

 Hello 111
 Hello 999
 Hello World
 Goodbye 999
 Goodbye 999

コンパイラオプション -C=recursion(または -C, -C=all)を付加すれば、

実行時エラー: rtc_recursion.f90, line 5: 再帰呼出しが非再帰手続きMAIN:DISPATCHに対して行われました
致命的なエラーでプログラムが終了しました

未定義の変数

[ rtc_undefined.f90 ]

program main
  implicit none
  integer i, x(5)
  do i = 1, 3
    x(i) = i
  end do
  print *, x ! 未定義の要素 x(4), x(5) を参照している。
end program

このプログラムを実行すると、例えば、

 1 2 3 0 1581952

コンパイラオプション -C=undefined を付加すれば、

実行時エラー: rtc_undefined.f90, line 7: 定義されていない変数Xへの参照が行われました
致命的なエラーでプログラムが終了しました

Results matter. Trust NAG.
Privacy Policy | Trademarks