Pointers Fortran过程指针指向不执行任何操作的子例程

Pointers Fortran过程指针指向不执行任何操作的子例程,pointers,fortran,procedure,Pointers,Fortran,Procedure,我有这样的代码 : 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()似乎不起作用。

我有这样的代码

:
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

然而,这看起来很愚蠢,而且我在编译代码时收到了很多编译警告,因为没有使用这些参数。有没有更聪明的方法来做到这一点?

如果没有什么有用的事情要做,可以将过程指针置为空,然后在通过指针调用过程之前测试关联状态

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

如果没有任何有用的操作,可以将过程指针置为空,然后在通过指针调用过程之前测试关联状态

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

如果您真正关心的是循环中的
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
do ii = 1, big_number
  call x(...)
  if (condition) then
    call p(i,j,k)
  end if
end do
然后在此版本上执行一些计时,然后在循环中包含
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
do ii = 1, big_number
  call x(...)
  if (condition) then
    call p(i,j,k)
  end if
end do

我宁愿猜测它们之间不会有任何显著的区别,因为循环中的子例程调用可能已经给您带来了比
if
语句引起的开销大得多的开销。

如果您真正关心的是循环中的
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
do ii = 1, big_number
  call x(...)
  if (condition) then
    call p(i,j,k)
  end if
end do
然后在此版本上执行一些计时,然后在循环中包含
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
do ii = 1, big_number
  call x(...)
  if (condition) then
    call p(i,j,k)
  end if
end do

我想您不会看到它们之间有任何显著的区别,因为循环中的子程序调用可能已经给您带来了比
if
语句引起的开销大得多的开销。

我之所以要这样做,是因为我可以避免do循环中的条件判断。如果我按照你的方式做,这将与将If(…)calljob1放入do循环相同。那么这里就不需要过程指针了。很抱歉,我没有明确说明我的观点。如果您可以执行
调用p(…)
,并让编译器自动决定调用过程指针
p
,如果它指向某个对象,或者如果指针为空,则决定不调用任何对象,那么编译器将在幕后执行If,就像这样。出于对运行时速度的考虑,如果编译器自动测试过程指针是否为空,或者如果您必须写出
if(associated(p))
test,那么会有什么区别呢,如果执行速度激发了您的需求,那么我希望指针指向的过程的动态调用的开销无论如何都要大于一个简单的条件测试(即调用一个只需测试逻辑而不调用过程的过程)。在执行方面,这两个选项在实际程序的上下文中都很可能是无关紧要的。如果您的需求是由其他情况驱动的,那么了解它是什么会有所帮助。我想这样做的原因是我可以避免在do循环中进行有条件的判断。如果我按照你的方式做,这将与将If(…)calljob1放入do循环相同。那么这里就不需要过程指针了。很抱歉,我没有明确说明我的观点。如果您可以执行
调用p(…)
,并让编译器自动决定调用过程指针
p
,如果它指向某个对象,或者如果指针为空,则决定不调用任何对象,那么编译器将在幕后执行If,就像这样。出于对运行时速度的考虑,如果编译器自动测试过程指针是否为空,或者如果您必须写出
if(associated(p))
test,那么会有什么区别呢,如果执行速度激发了您的需求,那么我希望指针指向的过程的动态调用的开销无论如何都要大于一个简单的条件测试(即调用一个只需测试逻辑而不调用过程的过程)。在执行方面,这两个选项在实际程序的上下文中都很可能是无关紧要的。如果您的需求是由其他情况驱动的,那么了解它是什么会有所帮助。