0

私はこのようなコードを持っています

:
procedure(),pointer :: p
if ()
  p => job1
else
  p => job2
endif

do i=1,a_big_number
  call x(...)
  call p(i,j,k)
enddo

サブルーチン「job1」は何らかの作業を行いますが、サブルーチン「job2」は何もしません。つまり、状況によっては、「x」と「job1」を完了する必要があります。他の状況では、「x」を実行するだけで済みます。私の質問は、job2 をどのように定義すればよいかです。null() を使用してもうまくいかないようです。私が今していることは次のようなものです:

subroutine job2(i,j,k)
integer,intent(in) :: i,j,k
end subroutine

しかし、これはばかげているように見えます。これらの引数が使用されていなかったため、コードをコンパイルしたときに多くのコンパイル警告が表示されました。これを行うよりスマートな方法はありますか?

4

2 に答える 2

3

何もする必要がない場合は、プロシージャ ポインタを無効にし、ポインタを介してプロシージャを呼び出す前に、関連付けの状態をテストできます。

PROCEDURE(interface_that_matches_job1), POINTER :: p
IF (...) THEN
  p => job1
ELSE
  NULLIFY(p)   ! Or p => NULL()
END IF

DO i = 1, a_big_number
  CALL x(...)
  IF (ASSOCIATED(p)) CALL p(i,j,k)
END DO
于 2013-03-09T00:22:50.940 に答える
0

あなたの懸念が本当にループ内のステートメントに関するものである場合は、ステートメントをループの外にif置くことができます:if

if (condition) then
  do ii = 1, big_number
    call x(...)
    call p(i,j,k)
  end do
else
  do ii = 1, big_number
    call x(...)
  end do
end if

次に、このバージョンでいくつかのタイミングを実行してからif、ループ内にあるバージョンで実行します。

do ii = 1, big_number
  call x(...)
  if (condition) then
    call p(i,j,k)
  end if
end do

ifループ内のサブルーチン呼び出しは、ステートメントによって引き起こされるオーバーヘッドよりもはるかに大きなオーバーヘッドをすでに与えている可能性があるため、それらの間に大きな違いは見られないと思います。

于 2013-03-09T07:29:16.283 に答える