オブジェクトのリンク#

最も単純なものを除き、ほぼすべてのプログラムはさまざまな部品から構成されています。このような状況を詳しく見ていきましょう。

これは関数をテーブル化するための一般的なプログラムです(ソースコードは “tabulate.f90”)。

program tabulate
    use user_functions

    implicit none
    real    :: x, xbegin, xend
    integer :: i, steps

    write(*,*) 'Please enter the range (begin, end) and the number of steps:'
    read(*,*)  xbegin, xend, steps

    do i = 0, steps
        x = xbegin + i * (xend - xbegin) / steps
        write(*,'(2f10.4)') x, f(x)
    end do
end program tabulate

use ステートメントに注目してください。これは関数 f を定義する場所です。

プログラムを汎用的にするために、特定のソースコード(関数 f の実装)を、一般的なソースコードから分離します。これを実現する方法はいくつかありますが、1つの方法は別のソースファイルに入れることです。一般プログラムをユーザーに提供し、ユーザーが特定のソースコードを提供できます。

例のために、関数がソースファイル “functions.f90” に次のように実装されているとします。

module user_functions
    implicit none
contains

real function f( x )
    real, intent(in) :: x
    f = x - x**2 + sin(x)
end function f

end module user_functions

この特定の関数を使ってプログラムをビルドするには、2つのソースファイルをコンパイルし、リンクステップを通じて1つの実行可能プログラムに結合する必要があります。「tabulate」プログラムはモジュール「function」に依存するため、最初にモジュールを含むソースファイルをコンパイルする必要があります。これを行うための一連のコマンドは次のとおりです。

$ gfortran -c functions.f90
$ gfortran tabulate.f90 functions.o

最初のステップではモジュールをコンパイルし、その結果、オブジェクトファイル “functions.o” とモジュールの中間ファイル “user_functions.mod” が生成されます。このモジュールファイルには、コンパイラが関数 f がこのモジュールで定義されていること、およびそのインターフェースが何であるかを判断するために必要なすべての情報が含まれています。この情報は重要です。これにより、コンパイラは関数を正しい方法で呼び出しているかどうかをチェックできます。間違いを犯し、関数の引数を1つではなく2つで呼び出した可能性があります。コンパイラが関数のインターフェースについて何も知らない場合、何もチェックできません。

2番目のステップでは、コンパイラを次のような方法で呼び出します。

  • ファイル “tabulate.f90” を(モジュールファイルを使用して)コンパイルします。

  • リンカーを呼び出して、オブジェクトファイル tabulate.o と functions.o を実行可能プログラムに結合します。デフォルト名は “a.out” または “a.exe” です(別の名前が必要な場合は、オプション “-o” を使用します)。

一般的には見えませんが、リンカーはこのリンクステップで、ランタイムライブラリである多数の追加ファイルも追加します。これらのランタイムライブラリには、「標準」のものがすべて含まれています。画面への入出力を実行する低レベルルーチン、sin 関数などです。

詳しい内容を知りたい場合は、オプション “-v” を追加してください。これにより、コンパイラは詳細なすべてのステップを報告するようになります。

最終結果である実行可能プログラムには、コンパイルされたソースコードと、プログラムが機能するためのさまざまな補助ルーチンが含まれています。また、いわゆる動的ランタイムライブラリ(WindowsではDLL、Linuxでは共有オブジェクトまたは共有ライブラリ)への参照も含まれています。これらのランタイムライブラリがないと、プログラムは起動しません。