3

このようなモジュールに関数があります(誰かが興味を持っている場合は、この関数です)

MODULE MYMODULE

    IMPLICIT NONE
    ! Some random stuff
    CONTAINS

        CHARACTER*255 FUNCTION strtok ( source_string, delimiters )
         [...]
        END FUNCTION strtok

        SUBROUTINE DO_SOMETHING ( )
           CHARACTER(LEN=255) :: strtok
           [...] ! 
        END SUBROUTINE DO_SOMETHING

END MODULE MYMODULE

この関数は、C の文字列トークナイザーのバージョンであり、サブルーチンstrtokからこの関数を使用します。DO_SOMETHINGを定義する必要があります。定義strtokしないと、gfortran が定義されていないと文句を言います。ただし、コードをコンパイルしてメイン プログラムにリンクすると、リンカは への未定義の参照について不平を言いstrtok_ます。両方とも同じモジュールにあり、表示されるはずなので、なぜそうなのかわかりません。同じモジュール内の他の関数とサブルーチンには、この問題はありません。これは、これが文字*を返す関数であるという事実と関係がありますか?

4

2 に答える 2

6

以下では、以下の完全な例を使用して説明します (コンパイルしてリンクして、試してみることができます)。

module mymodule
contains
  integer function foo ()
    foo = 1
  end function

  integer function bar ()
    integer :: foo
    bar = foo()
  end function
end module

program test
  use mymodule
  print *, bar()
end

function のコードではbar、宣言integer :: fooは以下と厳密に同等です。

integer, external :: foo

したがって、 のコードではbar、明示的に次のように述べています。

「あなたがアクセスできる名前のシンボルがすでにあるかもしれませんが、今後、 fooそれを使用するときは、この名前の外部関数であることを意味します」

externalしたがって、これは有効なコードであり、コンパイラはという名前の関数を提供することを期待していますfoo。そうでないため (モジュール関数は外部ではない)、リンクに失敗します。次のコードを追加することにより、外部foo関数を提供できます (モジュール内ではなく、同じファイルの最後にのみ)。

integer function foo ()
  foo = 42
end function

この関数本体を追加すると、コードがコンパイルされ、出力が次のようになります42(モジュール関数ではなく、外部関数が呼び出されるため)。

integer :: fooまた、 のコードの行をコメントアウトするとbar、シンボルfooはモジュール関数に解決され、名前付きの外部関数を提供するかどうかに関係なく呼び出されますfoo(したがって、出力は になります1)。

結論:コンパイラのバグではなく、言語の古い機能 (外部宣言) の誤用です。正直なところ、external少なくともここで問題を強調していたであろう宣言をそのように明示的にマークする方が良いと思います.

于 2010-10-31T15:11:04.490 に答える
1

あなたが投稿した不完全なソースコードから判断すると、これは問題のある行である可能性があると思います。

CHARACTER(LEN=255) :: strtok

サブルーチンDO_SOMETHINGと関数strtokは同じモジュール内にあるため、互いの定義を自動的に認識します(明示的なインターフェイスがあります)。strtokつまり、内部で関数の型を再宣言する必要がないだけでなくDO_SOMETHING、実際に行われるのは、この行strtokがサブルーチンのスコープで指定された新しい文字変数を宣言DO_SOMETHINGし、同じ名前のモジュール関数を上書きすることです。

基本的に、サブルーチン内では、識別子strtokは変数を参照するため、その名前で関数を参照しようとすると、コンパイラーはそれを認識しません。
うーん、これを書いているので、リンクエラーではなくコンパイル時エラーが発生するはずだと思い始めています。それでも、私が言及した行をコメントアウトして試してみる価値があるかもしれません。

于 2010-10-22T23:53:44.680 に答える