6

このコードがあれば

module test
contains
   subroutine xx(name)
      character(len=20), intent(in), optional :: name

      if (present(name)) then
         print *, name
      else
         print *, "foo"
      endif
   end subroutine
end module
program x
   use test

   call xx()
   call xx("foo2")
end program

「foo2」の長さが20ではないため、コンパイルされず、コンパイラーは文句を言います

test.f90(17): error #7938: Character length argument mismatch.   ['foo2']
   call xx("foo2")
-----------^

サブルーチンのダミー len 仕様を変更せずに、どうすればこれを機能させることができますか? 中間変数を同じ長さで宣言し、呼び出し時にそれを渡すことは必須ですか?

4

3 に答える 3

8

標準語は理解しにくい場合があります。@kemiistoが長さ(dummy arg) <= length(実際の引数)を必要とするものとして引用している句を読みました。ここで長さ(dummy arg) = 20およびlength (actual arg) = 4、したがって長さ(dummy arg) > length (actual arg)、これは句で許可されていません。この句では、必要に応じて、ダミーを空白で埋めるのではなく、ダミーと一致するように実際の値を切り捨てることについて説明しています。

で置き換えるcharacter(len = 20)とコードは機能character(len = *) しますダミー引数の指定の長さを変更したくないので、これに問題はありますか?

于 2011-01-25T04:16:21.663 に答える
2

len=20このエラーが発生する理由は、メソッドが仮引数に文字まで読み書きできるためnameです。文字列リテラルがこの量より少なく、コンパイラがこの事実を警告しています。宣言されていてもintent(in)、実際の引数の長さを超えて読み取り、アクセス違反などを引き起こす可能性があります。

読み書きしても安全な文字数を決定するときは、おそらくlen=*仮引数に固執し、 lenorを使用する必要があります。len_trim

または、 を保持する必要がある場合はlen=20、そのメソッドに値を渡すために使用される一時変数を使用する必要があります。または、のような醜いもの"hello"//repeat(" ", 15)

于 2011-02-03T17:12:21.117 に答える
2

標準に準拠した動作のように思えます。

Fortran 2003、12.4.1.2 ダミー データ オブジェクトに関連付けられた実際の引数

スカラー仮引数がデフォルト文字型の場合、仮引数の長さ len は、実引数の長さ以下でなければなりません。仮引数は、実引数の左端の len 文字に関連付けられます。

ただし、gfortran は警告メッセージを表示するだけです

警告: 実引数の文字長が仮引数 'name' より短い (4/20) at (1)

その点では、Intel Fortran コンパイラの方がより標準に準拠しているようです。したがって、中間変数がおそらく唯一のオプションです。

または、コードに変数がないため、実際には変数を宣言するだけでもオプションです。あなたは文字通り定数を持っています。とにかく、ハードコードされた値は良い考えではありません。=)

于 2011-01-24T11:18:33.873 に答える