Fortran Builder FAQ for Error

エラーに関する、よくある質問とその答え


  • 「KIND 値 (*) が有効な表現方法ではありません」というエラーが出てコンパイルに通りません。 [答え]
  • 古い Fortran プログラム(レガシーコード)がコンパイルに通りません。 [答え]
  • 編集記述子 $(改行抑止)はサポートしていないのですか? [答え]
  • CDABS(A)、DCMPLX(X,Y)、DCONJG(Z)、DIMAG(Z)、DREAL(Z) はどうすれば利用できますか? [答え]
  • 関数 getarg はありますか? [答え]
  • 関数 getenv はありますか? [答え]
  • 関数 flush はありますか? [答え]
  • 関数 system はありますか? [答え]
  • 手続(関数、サブルーチン)fdate がコンパイルに通りません。 [答え]
  • サブルーチン idate がコンパイルに通りません。 [答え]
  • 関数 dtime や etime がコンパイルに通りません。 [答え]
  • Fortran の組込み関数(例えば、CDEXP)がコンパイルに通りません。 [答え]
  • 「入力バッファにおいてレコードが長すぎます」または「出力においてバッファオーバーフローが発生しました」というエラーはどういう意味ですか? [答え]
  • 「実行時エラー: *** 算術例外: 浮動小数ゼロ除算 - 終了します」というエラーが出て実行が途中で止まります。 [答え]
  • 「変数 ** はSAVE属性を指定するには大きすぎます(*********** バイト)」というエラーが出てコンパイルに通りません。 [答え]
  • 「... R_X86_64_PC32 against symbol ...」というリンクエラーが出てビルドに通りません。 [答え]
  • 「このアプリはお使いの PC では実行できません」というメッセージが出てプログラムが実行できません。 [答え]
  • 自力でエラーを解決することができません。エラーを解消するサービスはありますか? [答え]


質問 「KIND 値 (*) が有効な表現方法ではありません」というエラーが出てコンパイルに通りません。
答え

コンパイラによって kind 値の解釈が異なるために出ているエラーです。

多くのコンパイラは kind 値がデータバイト数を表す方法(バイト指定)か、もしくは1番から順番に値を割り振る方法(シーケンシャル指定)のどちらかを採用しています。
Fortran Builder(NAG Fortran コンパイラ)では、後者の順番に割り振る方法(シーケンシャル指定)をデフォルトで採用しているため、データバイト数を表す方法(バイト指定)で書かれたプログラムはこのようなエラーとなります。

Fortran Builder(NAG Fortran コンパイラ)では、コンパイラオプションの指定で kind 値にデータバイト数を利用することが可能です。
Fortran Builder メニューバー「プロジェクト > プロジェクトの設定」を開き、

Fortran コンパイラ > 基本設定 > Kind モード (-kind=) > バイト (=byte)

を指定してください。

移植性を考えたソースコードを作成する場合には、real(4) などのように kind 値を直接指定せずに、組込み関数 selected_real_kind や kind などを用いて kind 値を間接的に設定する方法(例えば、real(kind(1.0)) など)を推奨します。


質問 古い Fortran プログラム(レガシーコード)がコンパイルに通りません。
答え

Fortran Builder(NAG Fortran コンパイラ)はプログラムが Fortran 標準に準拠しているかどうかを厳しくチェックします。
新たなプログラムを作成する場合、これはコンパイラの本来あるべき姿とも言えますが、昔書かれたプログラム(レガシーコード)をコンパイルする際に厳しいチェックを望まない場合もあります。
このため、Fortran Builder(NAG Fortran コンパイラ)では、厳しいチェックを行わないことを指示するためのコンパイラオプションが用意されています。

Fortran Builder メニューバー「プロジェクト > プロジェクトの設定」を開き、

Fortran コンパイラ > 基本設定 > 古典的ソースコードのエラーを警告にする (-dusty)

を指定してください。
これにより、レガシーコードに良く見られるエラーを警告として扱うようになり、コンパイルが続行できます。

さらに必要であれば、

Fortran コンパイラ > 詳細設定 (1) > 警告表示選択 > 全て非表示

を指定して警告の出力を抑止することも可能です。


質問 編集記述子 $(改行抑止)はサポートしていないのですか?
答え

サポートしていません。

編集記述子 $(改行抑止)は Fortran 非標準であるため文法エラーとなります。

Fortran 標準では、改行を抑止する場合は write 文において advance='no' という指定を行います。
以下にプログラム例を示します。

プログラム例:

program advance_example
  implicit none
  integer age
  write (*, fmt='(a)', advance='no') "Enter your age: " ! 改行なし
  read *, age
  print *, "Your age is:", age
end program

出力例:

Enter your age: 20
 Your age is: 20

質問 CDABS(A)、DCMPLX(X,Y)、DCONJG(Z)、DIMAG(Z)、DREAL(Z) はどうすれば利用できますか?
答え

CDABS などの組込み関数は Fortran 標準の組込み関数ではありませんが、多くのコンパイラがこれら Fortran 非標準の組込み関数をサポートしています。

Fortran Builder(NAG Fortran コンパイラ)では Fortran 標準に準拠するために、Fortran 非標準の倍精度複素数組込み手続は、Fortran Builder メニューバー「プロジェクト > プロジェクトの設定」を開き、

Fortran コンパイラ > 基本設定 > 非標準の倍精度複素数組込み関数を有効にする (-dcfuns)

を指定した時にのみ利用可能となっています。


質問 関数 getarg はありますか?
答え

はい、Fortran Builder(NAG Fortran コンパイラ)は多くの POSIX システムコールを独自の組込みモジュールで提供しています。
これらにアクセスするためには、該当するモジュールを use 文により指定する必要があります。
getarg はモジュール f90_unix_env においてサブルーチンとして提供されます。
詳細につきましては、Fortran Builder ヘルプ「NAG Fortran Compiler, Release 7.2 マニュアル - 7.4 f90_unix_env」をご参照ください。

しかしながら、Fortran 標準の観点からは、Fortran 2003 から導入された組込みサブルーチン get_command_argument の利用が推奨されます。
Fortran 標準の組込みサブルーチン get_command_argument を利用したプログラム例を以下に示します。

program main
  implicit none
  integer i
  character (len=256) arg
  do i = 0, command_argument_count()
    call get_command_argument(i, arg)
    print *, trim(arg)
  end do
end program

質問 関数 getenv はありますか?
答え

はい、Fortran Builder(NAG Fortran コンパイラ)は多くの POSIX システムコールを独自の組込みモジュールで提供しています。
これらにアクセスするためには、該当するモジュールを use 文により指定する必要があります。
getenv はモジュール f90_unix_env においてサブルーチンとして提供されます。
詳細につきましては、Fortran Builder ヘルプ「NAG Fortran Compiler, Release 7.2 マニュアル - 7.4 f90_unix_env」をご参照ください。

しかしながら、Fortran 標準の観点からは、Fortran 2003 から導入された組込みサブルーチン get_environment_variable の利用が推奨されます。
Fortran 標準の組込みサブルーチン get_environment_variable を利用したプログラム例を以下に示します。

program environment_example
!
! This program displays the values of the environment variables FRED and USERNAME
! (if they exist).
!
  implicit none
  call show('FRED')
  call show('USERNAME')
contains
  subroutine show(name)
    character(*), intent(in) :: name
    character(:), allocatable :: value
    integer len, status
    intrinsic get_environment_variable
    call get_environment_variable(name, status=status, length=len)
    if (status == 1) then
      print *, 'Environment variable "', name, '" does not exist.'
    else if (status /= 0) then
      print *, 'Unexpected status', status, 'for environment variable "', name, '"'
    else
      allocate(character(len) :: value)
      call get_environment_variable(name, value=value)
      print *, 'The value of environment variable "', name, '" is "', value, '".'
    end if
  end subroutine
end program

質問 関数 flush はありますか?
答え

はい、Fortran Builder(NAG Fortran コンパイラ)は多くの POSIX システムコールを独自の組込みモジュールで提供しています。
これらにアクセスするためには、該当するモジュールを use 文により指定する必要があります。
flush はモジュール f90_unix_io においてサブルーチンとして提供されます。
詳細につきましては、Fortran Builder ヘルプ「NAG Fortran Compiler, Release 7.2 マニュアル - 7.7 f90_unix_io」をご参照ください。

しかしながら、Fortran 標準の観点からは、Fortran 2003 から導入された flush 文の利用が推奨されます。
flush 文を利用したプログラム例を以下に示します。

program slow_dots
!
! This program prints 10 dots, one per second, then finishes.
!
  use iso_fortran_env, only : output_unit
  implicit none
  integer i
  do i = 1, 10
    write (*, '(a)', advance='no') '.'
    call delay
    flush (output_unit)
  end do
  print *, 'Done.'
contains
  subroutine delay
    integer cps,start,now
    intrinsic system_clock
    call system_clock(count=start, Count_Rate=cps)
    if (start == -huge(start)) stop 'No clock.'
    do
      call system_clock(count = now)
      if (now < start .or. now >= start + cps) exit
    end do
  end subroutine
end program

質問 関数 system はありますか?
答え

はい、Fortran Builder(NAG Fortran コンパイラ)は多くの POSIX システムコールを独自の組込みモジュールで提供しています。
これらにアクセスするためには、該当するモジュールを use 文により指定する必要があります。
system はモジュール f90_unix_proc においてサブルーチンとして提供されます。
詳細につきましては、Fortran Builder ヘルプ「NAG Fortran Compiler, Release 7.2 マニュアル - 7.8 f90_unix_proc」をご参照ください。

しかしながら、Fortran 標準の観点からは、Fortran 2008 から導入された組込みサブルーチン execute_command_line の利用が推奨されます。
Fortran 標準の組込みサブルーチン execute_command_line を利用したプログラム例を以下に示します。

program main
  implicit none
  call execute_command_line('echo Hello World')
end program

質問 手続(関数、サブルーチン)fdate がコンパイルに通りません。
答え

手続(サブルーチン、関数)fdate は Fortran 標準の組込み手続ではありません。

代わりに、Fortran 標準の組込みサブルーチン date_and_time を以下のプログラム例を参考にご利用ください。

サブルーチン fdate の代替例:

subroutine fdate(dstr)
  implicit none
  character(len=*),intent(out) :: dstr
  character(len=3), parameter :: mstr(12) = (/ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', &
                                               'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' /)
  character(len=3), parameter :: dowstr(0:6) = (/ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' /)
  integer, parameter :: t(12) = (/ 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 /)
  integer ival(8), y, m, d, dow
  character(24) buf
  call date_and_time(values=ival)
  m = ival(2)
  y = ival(1)
  d = ival(3)
  ! Sakamoto's method
  if (m<3) y = y - 1
  dow = mod(y+y/4-y/100+y/400+t(m) + d, 7)
  write (buf, '(a3,1x,a3,1x,i2,1x,i2,":",i2.2,":",i2.2,1x,i4)') &
    dowstr(dow), mstr(m), d, ival(5), ival(6), ival(7), ival(1)
  dstr = buf
end subroutine

関数 fdate の代替例:

character(len=24) function fdate()
  implicit none
  character(len=3), parameter :: mstr(12) = (/ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', &
                                               'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' /)
  character(len=3), parameter :: dowstr(0:6) = (/ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' /)
  integer, parameter :: t(12) = (/ 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 /)
  integer ival(8), y, m, d, dow
  call date_and_time(values=ival)
  m = ival(2)
  y = ival(1)
  d = ival(3)
  ! Sakamoto's method
  if (m<3) y = y - 1
  dow = mod(y+y/4-y/100+y/400+t(m) + d, 7)
  write (fdate, '(a3,1x,a3,1x,i2,1x,i2,":",i2.2,":",i2.2,1x,i4)') &
    dowstr(dow), mstr(m), d, ival(5), ival(6), ival(7), ival(1)
end function

質問 サブルーチン idate がコンパイルに通りません。
答え

サブルーチン idate は Fortran 標準の組込みサブルーチンではありません。

代わりに、Fortran 標準の組込みサブルーチン date_and_time を以下のプログラム例を参考にご利用ください。

idate の代替例:

subroutine idate(iarray)
  implicit none
  integer iarray(3), ival(8)
  call date_and_time(values=ival)
  iarray(1) = ival(3)
  iarray(2) = ival(2)
  iarray(3) = ival(1)
end subroutine

質問 関数 dtime や etime がコンパイルに通りません。
答え

関数 dtime や etime は Fortran 標準の組込み関数ではありません。
代わりに Fortran 標準の組込みサブルーチン cpu_time や system_clock を以下のプログラム例「代替その1」を参考にご利用ください。
なお「代替その2」はそれぞれ Fortran Builder(NAG Fortran コンパイラ)独自の組込みモジュール f90_unix_env で提供される関数 times を利用したものとなります。

dtime の代替その1:

real function dtime(time)
  real time(2)
  double precision, save :: last_time = 0
  double precision this_time
  call cpu_time(this_time)
  time(1) = this_time - last_time
  time(2) = 0
  dtime = time(1)
  last_time = this_time
end function

dtime の代替その2:

real function dtime(time)
  use f90_unix_env, only : tms, times
  real time(2)
  type(tms), save :: lastbuf
  logical :: start = .true.
  type(tms) buffer
  integer junk
  junk = times(buffer)
  if (start) then
    lastbuf%utime = 0
    lastbuf%stime = 0
    start = .false.
  end if
  time(1) = buffer%utime - lastbuf%utime
  time(2) = buffer%stime - lastbuf%stime
  dtime = time(1) + time(2)
  lastbuf = buffer
end function

etime の代替その1:

real function etime(time)
  real time(2)
  call cpu_time(etime)
  time(1) = etime
  time(2) = 0
end function

etime の代替その2:

real function etime(time)
  use f90_unix_env, only : tms, times
  real time(2)
  type(tms) buffer
  integer junk
  junk = times(buffer)
  time(1) = buffer%utime
  time(2) = buffer%stime
  etime = buffer%utime + buffer%stime
end function

質問 Fortran の組込み関数(例えば、CDEXP)がコンパイルに通りません。
答え

Fortran 標準の組込み関数には総称名(例えば、EXP)と個別名(例えば、CEXP)があります。
コンパイルに通らない原因としては、Fortran 非標準の(特定のコンパイラが独自にサポートしている)個別名(例えば、CDEXP)の使用が考えれます。

解決策としては、個別名の代わりに総称名をご利用ください。
個別名は特定の精度に対応しますが、総称名はご利用のコンパイラがサポートする全ての精度に対応しており、引数の型と同じ型の戻り値を得ることができます。

Fortran 非標準の個別名をリストアップすることは不可能ですが、一般的なルールとして xFUN のような関数の代わりに FUN を使用してください。
ここで x は1文字または複数文字の個別名の接頭辞、FUN は数学関数の名前です。

良く利用される数学関数の名前:
ABS, ACOS, ASIN, ATAN, ATAN2, CONJG, COS, COSH, DIM, EXP, LOG, LOG10, MAX, MIN, SIGN, SIN, SINH, SQRT, TAN, TANH

典型的な個別名の接頭辞:
C, CD, CQ, D, DC, Q, Z

例えば、個別名 CEXP, DEXP, CDEXP, DCEXP, QEXP, CQEXP, ZEXP はどれも総称名 EXP に置き換えても同じ結果を得ることができます。

いくつかの組込み関数については、ルールが若干異なります。
xINT, xNINT(ここで x は上述した個別名の接頭辞)は、AINT, ANINT に置き換えてください。

接頭辞 C または D で始まる個別名の中には Fortran 標準の個別名(例えば、CEXP)もあることに注意してください。
しかし、いずれにせよ現在では(総称名の代わりに)個別名を用いるべき理由は特にありません。


質問 「入力バッファにおいてレコードが長すぎます」または「出力においてバッファオーバーフローが発生しました」というエラーはどういう意味ですか?
答え

これはファイルバッファの大きさを超えて formatted 入力または出力が行われたことを意味します。
デフォルトのバッファサイズは 1024 文字です。
これをより大きくする場合には open 文で「recl=バッファサイズ」と指定してください。

open (13, file="myfile", form="formatted", recl=2048)

この例では、バッファサイズを 2048 文字に拡張しています。
また、iolength 指定子を inquire 文で指定して recl 指定子に必要なサイズを求める事ができます。

inquire (iolength=irecl) my_big_array
open (13, file="dump", form="formatted", recl=irecl)

この例では、装置 13 に、my_big_array を読み書きするのに必要なサイズを設定しています。


質問 「実行時エラー: *** 算術例外: 浮動小数ゼロ除算 - 終了します」というエラーが出て実行が途中で止まります。
答え

多くのコンパイラ環境では、算術例外(ゼロ除算など)を無視して実行を継続する動作がデフォルトになっていますが、Fortran Builder(NAG Fortran コンパイラ)では、算術例外(ゼロ除算など)が発生した場合、そこで実行をストップしてエラーを出力する動作がデフォルトとなっています。

算術例外(ゼロ除算など)を無視して実行を継続したい場合は、Fortran Builder メニューバー「プロジェクト > プロジェクトの設定」を開き、

Fortran コンパイラ > 基本設定 > IEEE モード (-ieee=) > 全ての IEEE 算術機能 (=full)

を指定してください。

プログラム例:

program division_by_zero
  implicit none
  call sub(1.0, -2, 0, 2)
contains
  subroutine sub(x, n1, n2, n3)
    real x
    integer n1, n2, n3
    print *, x / n1
    print *, x / n2
    print *, x / n3
  end subroutine
end program
デフォルトでは、ゼロ除算でエラーとなり実行が止まります。
  -0.5000000
致命的なエラーでプログラムが終了しました
コンパイラオプション -ieee=full を指定した場合は、最後まで実行を行います。
  -0.5000000
 Infinity
   0.5000000

質問 「変数 ** はSAVE属性を指定するには大きすぎます(*********** バイト)」というエラーが出てコンパイルに通りません。
答え

静的にメモリに割り当てられている変数(配列)の大きさが 2 GB を超えているために出ているコンパイルエラーです。

Windows OS は(Linux OS とは異なり)2 GB を超える静的メモリをサポートしません。

プログラム例(静的な配列):

program big_array_static
  implicit none
  double precision a(1024, 512, 512)
  a = 8d0
  print '(i10)', int(sum(a), kind=4)
end program

コンパイルエラー:

変数AはSAVE属性を指定するには大きすぎます(2147483648バイト)

このような場合、変数(配列)を動的にメモリに割り当てるようにする必要があります。

動的メモリ割り当ては、allocatable や pointer などを用いて行うことができます。
(詳しくは、手近の Fortran 言語の文法書をご参照ください。)

プログラム例(動的な配列):

program big_array_dynamic
  implicit none
  double precision, allocatable :: a(:, :, :)
  allocate(a(1024, 512, 512))
  a = 8d0
  print '(i10)', int(sum(a), kind=4)
end program

実行結果:

2147483648

質問 「... R_X86_64_PC32 against symbol ...」というリンクエラーが出てビルドに通りません。
答え

プログラムのリンク時に静的メモリが 2 GB を超えている可能性があります。

Windows OS は(Linux OS とは異なり)2 GB を超える静的メモリをサポートしません。

このような場合、静的メモリのサイズが 2 GB 以下になるように、(静的にメモリに割り当てられている)大きなサイズの変数(配列)を、動的にメモリに割り当てるようにする必要があります。

動的メモリ割り当ては、allocatable や pointer などを用いて行うことができます。
(詳しくは、手近の Fortran 言語の文法書をご参照ください。)

プログラム例(動的な配列):

program big_array_dynamic
  implicit none
  double precision, allocatable :: a(:, :, :)
  allocate(a(1000, 512, 512))
  a = 8d0
  print '(i10)', int(sum(a))
end program

実行結果:

2097152000

質問 「このアプリはお使いの PC では実行できません」というメッセージが出てプログラムが実行できません。
答え

プログラムの実行時に静的メモリが 2 GB を超えている可能性があります。

Windows OS は(Linux OS とは異なり)2 GB を超える静的メモリをサポートしません。

プログラム例(静的な配列):

program big_array_static
  implicit none
  double precision a(1000, 512, 512)
  a = 8d0
  print '(i10)', int(sum(a))
end program

実行結果(OS が出すメッセージ):

このアプリはお使いの PC では実行できません

このプログラムは実行時に静的メモリが 2 GB を超えるため、Windows では実行できません。

このような場合、実行時の静的メモリのサイズが 2 GB 以下になるように、(静的にメモリに割り当てられている)大きなサイズの変数(配列)を、動的にメモリに割り当てるようにする必要があります。

動的メモリ割り当ては、allocatable や pointer などを用いて行うことができます。
(詳しくは、手近の Fortran 言語の文法書をご参照ください。)

プログラム例(動的な配列):

program big_array_dynamic
  implicit none
  double precision, allocatable :: a(:, :, :)
  allocate(a(1000, 512, 512))
  a = 8d0
  print '(i10)', int(sum(a))
end program

実行結果:

2097152000

質問 自力でエラーを解決することができません。エラーを解消するサービスはありますか?
答え

有償のサービスとなりますが、古い Fortran プログラムのエラーの解消やモダナイゼーションを行うサービスを提供してます。

Fortran コンサルティング

お気軽にお問い合わせください。


Privacy Policy  /  Trademarks