forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Optional arrays arguments

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
simon



Joined: 05 Jul 2006
Posts: 268

PostPosted: Tue Sep 22, 2015 4:23 am    Post subject: Optional arrays arguments Reply with quote

I believe that it is part of the Fortran standard that optional arguments can be passed as optional arguments to other routines without having to check whether they are present - their present status is passed automatically.

But consider the following code, which does not work in either FTN95 or NAGWare. My understanding is that the call to s2 should definitely work, but what about the call to s3 at line 11? This generates an error message indicating that the optional arguments are undefined. Indeed the optional arguments are not passed to s1, but given that they are optional in s3 surely that should not matter.

Code:
PROGRAM m
!
 CALL s1 ()
!
CONTAINS
!
 SUBROUTINE s1 (i,j)
  INTEGER,               INTENT(IN), OPTIONAL :: i
  INTEGER, DIMENSION(2), INTENT(IN), OPTIONAL :: j
  CALL s2 (i1=i)
  CALL s3 (j1=j(1),j2=j(2))
 END SUBROUTINE s1
!
 SUBROUTINE s2 (i1)
  INTEGER, INTENT(IN), OPTIONAL :: i1
  IF (PRESENT(i1)) THEN
     PRINT *, i1
  ELSE
     PRINT *, 'N/A'
  END IF
 END SUBROUTINE s2
!
 SUBROUTINE s3 (j1,j2)
  INTEGER, INTENT(IN), OPTIONAL :: j1
  INTEGER, INTENT(IN), OPTIONAL :: j2
  IF (PRESENT(j1)) THEN
     PRINT *, j1
  ELSE
     PRINT *, 'N/A'
  END IF
  IF (PRESENT(j2)) THEN
     PRINT *, j2
  ELSE
     PRINT *, 'N/A'
  END IF
 END SUBROUTINE s3
END PROGRAM m
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1886

PostPosted: Tue Sep 22, 2015 1:49 pm    Post subject: Reply with quote

This is an example that justifies one's sitting on the fence with a copy of the Fortran standard, but here is my take: Line 11 of your code tries to split a hair that is not present, so the code is not valid. Whether a compiler should detect the violation at compile time or at run time is a separate question.

Let us look at the question from an implementation perspective, as well. When j is used as an argument, whether present or not, its address is passed; a NULL gets passed if it is not present. However, you want to pass j(1) and j(2) as arguments, and that cannot be done unless you start treating NULLs in the same way as infinity, i.e., half a NULL equals a NULL, etc.

I am open to arguments supporting the claim that the opposite should be true.

P.S.: After writing my reply above, I tested your code with the Sun Fortran compiler 12.4 on Linux. The run-time error was:
Code:
 ******  FORTRAN RUN-TIME SYSTEM  ******
 Attempting to use a missing optional dummy 'J'
 Location:  line 11 column 15 of 'pres.f90'
Aborted
It is worth noting that Line-11, Column 15 is where we have "j(1)...".
Back to top
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Mon Sep 28, 2015 9:56 pm    Post subject: Reply with quote

I thought the problem here was that the actual arguments are arrays but the dummy arguments are scalars?

Generally speaking, if a subprogram "A" has optional dummy arguments there is no need to test using present() if they are simply passed and associated to optional dummy arguments in another subprogram "B".

So, if A and B have explicit interfaces, there is no need to write
Code:

subroutine A(x)
   integer, optional :: x
   if (present(x)) then
      call B(x)
   else
      call B()
   end if
end subroutine A

subroutine B(x)
   integer, optional :: x
   if (present(x)) then
      ! ... may reference x
   end if
end subroutine B


Instead you can just say:

Code:

subroutine A(x)
   integer, optional :: x
   call B(x)
end subroutine A

subroutine B(x)
   integer, optional :: x
   if (present(x)) then
      ! ... may reference x
   end if
end subroutine B


I think this works ok in FTN95. But mixing array/non-array arguments may confuse the compiler.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1886

PostPosted: Wed Sep 30, 2015 3:19 pm    Post subject: Reply with quote

DavidB, only the optional second argument of Subroutine S1 is an array. In the only call of S1 in the example, this argument is absent.

The main issue is: if an optional argument is an array (or structure), in an instance where it is not present, how should array elements (or structure components) be treated? I think that consistency requires that if J is an optional array arguments, both J(1), J(2), etc., should all be seen as absent.

Here is a second example to make this clear.
Code:

PROGRAM absent
type pair
  integer first,second
end type
!         
 CALL s1 ()
!
CONTAINS
!
 SUBROUTINE s1 (j)
  type(pair), INTENT(IN), OPTIONAL :: j
!
 CALL s2 (j1=j%first,j2=j%second)
 END SUBROUTINE s1
!
 SUBROUTINE s2 (j1,j2)
  INTEGER, INTENT(IN), OPTIONAL :: j1, j2
  write(*,10)loc(j1),loc(j2)
10 format("Subroutine s2, argument addresses: ",4x,Z8.8,4x,Z8.8)
  IF (PRESENT(j1)) THEN
       PRINT *, 'j1 seems to be present'
     PRINT *, 'j1 = ',j1
  ELSE
     PRINT *, 'j1 is not present'
  END IF
  IF (PRESENT(j2)) THEN
       PRINT *, 'j2 seems to be present'
     PRINT *, 'j2 = ',j2
  ELSE
     PRINT *, 'j2 is not present'
  END IF
 END SUBROUTINE s2
END PROGRAM absent

This code prints
Code:

Subroutine s2, argument addresses:     F0F0F0F0    F0F0F0F4
 j1 is not present
 j2 seems to be present

and then it crashes.

The signature F0F0F0F0 appears to have been adopted as the representation for Optional, Not Present. On the other hand, F0F0F0F4 has no special significance and causes the crash when dereferenced.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group