Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Optional Arguments and Their Uses.

Ilie__Daniel
Beginner
3,294 Views

Dear All,

I was wondering: is it worth considering to code using optional arguments or should they be avoided at any cost? Is there a loss in performance if optional arguments are used?

I have read the FORTRAN Newsletter Articles posted by Dr.Fortran.

Looking forward to your thoughts,

Daniel.

0 Kudos
15 Replies
jimdempseyatthecove
Honored Contributor III
3,294 Views

If you have a requirement for optional arguments, then use them, following the rules of use (principally that of requiring the use of an INTERFACE). There are many other such rules in the specification. It is the programmer's responsibility to follow the rules.

Steve,

Seeing that a subroutine or function can be attributed with a name alias, was it ever considered that for subroutines and functions containing optional arguments to generate a name that is aliased to something that looks like but is in fact not that which is supplied in the source code. IOW a decorated name. Additional, any INTERFACE declaration of the subroutine or function with the optional argument(s) would generate the same aliased name (internal mangled name would be more appropriate here). The purpose being that this would make it difficult to call the subroutine or function without an INTERFACE.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
3,294 Views

Jim,

The IA-32 STDCALL convention would at least catch not passing the right number of arguments. But that also creates a lot of problems on its own so it's not astonishing that it didn't persist in "AMD64". What you ask is effectively C++ name mangling, and I doubt Fortran will ever go there. The F2015 IMPLICIT (EXTERNAL:NONE) can help here (not yet in ifort.)

0 Kudos
FortranFan
Honored Contributor III
3,294 Views

Avoid any advice that asks you to avoid anything at any cost..

0 Kudos
Steven_L_Intel1
Employee
3,294 Views

I'll comment that the only performance impact of optional arguments is the passing of a 0 address on the call and any tests for PRESENT(). Otherwise they are no different from other arguments and one could argue that they're more efficient than having multiple versions of routines.

0 Kudos
FortranFan
Honored Contributor III
3,294 Views

jimdempseyatthecove wrote:

..

Steve,

Seeing that a subroutine or function can be attributed with a name alias, was it ever considered that for subroutines and functions containing optional arguments to generate a name that is aliased to something that looks like but is in fact not that which is supplied in the source code. IOW a decorated name. Additional, any INTERFACE declaration of the subroutine or function with the optional argument(s) would generate the same aliased name (internal mangled name would be more appropriate here). The purpose being that this would make it difficult to call the subroutine or function without an INTERFACE.

Jim Dempsey

Jim,

I wonder if it won't be better if a coder took control of the matter and made suitable use of private and public attributes of module entities to achieve what you suggest, "make it difficult to call the subroutine or function without an INTERFACE."  In fact, it can be made effectively impossible as follows:

module m

   implicit none

   private

   interface greet
      module procedure mygreet
   end interface
   public :: greet

contains

   subroutine mygreet(message)

      character(len=*), optional, intent(in) :: message

      if (present(message)) then
         print *, message
      else
         print *, "Hello World!"
      end if

      return

   end subroutine mygreet

end module m

 

0 Kudos
FortranFan
Honored Contributor III
3,294 Views

Steve Lionel (Intel) wrote:

I'll comment that the only performance impact of optional arguments is the passing of a 0 address on the call and any tests for PRESENT(). Otherwise they are no different from other arguments and one could argue that they're more efficient than having multiple versions of routines.

To add to Steve's comment, Fortran 2008 standard makes the use of procedures with optional arguments even easier by allowing NULL pointer or an unallocated allocatable variable to indicate an absent argument.  This can be very convenient in the consumption of procedures that have multiple optional arguments as shown by Metcalf et al.

Steve,

The following simple code encounters a compiler error with Intel Fortran (16.0 beta, update 2).  I can't find anything in the Fortran 2008 standard that supports the compiler assertion about requiring a MOLD with the NULL pointer.  Is this correct?  If so, I must have overlooked something.  Can you please check this and provide the supporting standard documentation?  Thanks, 

module m

   implicit none

   private

   interface greet
      module procedure mygreet
   end interface
   public :: greet

contains

   subroutine mygreet(message)

      character(len=*), optional, intent(in) :: message

      if (present(message)) then
         print *, message
      else
         print *, "Hello World!"
      end if

      return

   end subroutine mygreet

end module m
program p

   use m, only : greet

   implicit none

   call greet( null() )

   stop

end program p
1>Compiling with Intel(R) Visual Fortran Compiler 16.0.0.063 [Intel(R) 64]...
1>p.f90
1>C:\..\p.f90(7): error #8613: Intrinsic NULL() must have the MOLD argument if it is an actual argument corresponding to a dummy argument with assumed type parameters.
1>compilation aborted for C:\..r\p.f90 (code 1)

 

0 Kudos
IanH
Honored Contributor III
3,294 Views

FortranFan wrote:

I wonder if it won't be better if a coder took control of the matter and made suitable use of private and public attributes of module entities to achieve what you suggest, "make it difficult to call the subroutine or function without an INTERFACE."  In fact, it can be made effectively impossible as follows...

I may have misunderstood Jim's and your points... but it is impossible to invoke any module procedure by a name (as opposed to by a reference) without there being an explicit interface.  Public/private and the generic interface don't change much here.

With submodule support about to land, there are precious few reasons for writing external subprograms.

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,294 Views

Steve,

>> The F2015 IMPLICIT (EXTERNAL:NONE) can help here (not yet in ifort.)

Can you push for an option to perform the above and/or a warning.

ForetranFan,

>>I wonder if it won't be better if a coder took control of the matter and made suitable use of private and public attributes of module entities to achieve what you suggest

Often the coder is not in control of the entirety of the code, and some of the code the are working with goes back 50 years. Using the (assumed to be) option ?? /warn:no-interface ?? one could locate the non-interfaced externals then looking up the specification for the routine, write an appropriate interface and place this into an interfaces module (you my have multiple of these for different groupings of external libraries).

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
3,294 Views

FortranFan:

13.7.1.125 NULL ([MOLD])

23 5 If MOLD is absent, the characteristics of the result are determined by the entity with which the reference is
24 associated. See Table 13.2. MOLD shall not be absent in any other context. If any type parameters of the
25 contextual entity are deferred, those type parameters of the result are deferred. If any type parameters of the
26 contextual entity are assumed, MOLD shall be present.

While not specifically relating to your query, the standard also requires MOLD to be present if the type of the actual argument is needed to resolve a generic reference.

0 Kudos
FortranFan
Honored Contributor III
3,294 Views

Steve Lionel (Intel) wrote:

FortranFan:

13.7.1.125 NULL ([MOLD])

23 5 If MOLD is absent, the characteristics of the result are determined by the entity with which the reference is
24 associated. See Table 13.2. MOLD shall not be absent in any other context. If any type parameters of the
25 contextual entity are deferred, those type parameters of the result are deferred. If any type parameters of the
26 contextual entity are assumed, MOLD shall be present.

While not specifically relating to your query, the standard also requires MOLD to be present if the type of the actual argument is needed to resolve a generic reference.

Steve,

Thanks.  But in the context of Fortran 2008 standard change that allows a null pointer or an unallocated allocatable to denote an absent argument, how does MOLD come into play?  And if it does, how is assumed-shape array declaration for an optional dummy argument different from an assumed-length character dummy argument that is optional?

Note the following simple code compiles and works ok with gfortran, but Intel Fortran gives a compiler error.  Is Intel Fortran correct?  If so, how?  Note Intel Fortran does not raise an error with assumed-size array optional argument, only with assumed-length character optional argument.

module m

   implicit none

   private

   public :: foo
   public :: bar

contains

   subroutine foo( iarr )

      integer, optional, intent(in) :: iarr(:)

      if (present(iarr)) then
         print *, iarr
      else
         print *, " nothing to print."
      end if

      return

   end subroutine foo

   subroutine bar( str )

      character(len=*), optional, intent(in) :: str

      if (present(str)) then
         print *, str
      else
         print *, " nothing to print."
      end if

      return

   end subroutine bar

end module m
program p

   use m, only : foo, bar

   implicit none

   call foo( null() )
   call bar( null() )

   stop

end program p
1>p.f90
1>C:\..\p.f90(8): error #8613: Intrinsic NULL() must have the MOLD argument if it is an
actual argument corresponding to a dummy argument with assumed type parameters.
1>compilation aborted for C:\..\p.f90 (code 1)
1>

Thanks,

0 Kudos
Steven_L_Intel1
Employee
3,294 Views

Intel Fortran is correct here. Array shape is not a type parameter, character length is.Offhand I don't know why the standard has this rule, but it does, and I assume there was a good reason for it.

0 Kudos
FRESHIPALI_R_
Beginner
3,294 Views

Hi! Mr.Steve.

I have some troubles in arguments section in my code.

I have tried to compile a project composed of large codes which all were written in fortran language using Microsoft Visual Studio and Compiler was Intel Visual Fortran 11.1.038. Please note that this project have been already compiled using Compaq Visual Fortran and got the outputs well.

Problem is, the method to migrate from CVF to IVF works for some projects only while other projects are not giving outputs properly.

So, I have just tried to create a new project using the same codes and tried to run using IVF. When I was doing so,  i have got following errors. I have listed below errors for your reference and also I am seeking your guidance regarding with these errors.

Error    2     error #6631: A non-optional actual argument must be present when invoking a procedure with an explicit interface.   [PS_OUT]       
Error    3     error #6631: A non-optional actual argument must be present when invoking a procedure with an explicit interface.   [TS_OUT]       
Error    6     error #7836: If the actual argument is scalar, the corresponding dummy argument shall be scalar unless the actual argument is an element of an array that is not an assumed-shape or pointer array, or a substring of such an element.   [YTAB]    
Error    4    Compilation Aborted (code 1)    
Error    7    Compilation Aborted (code 1)

Also please note that I have got these error when I was performing Build.

Thank you.  

   

 

 

0 Kudos
FRESHIPALI_R_
Beginner
3,294 Views

Hi! Mr.Steve.

I have some troubles in arguments section in my code.

I have tried to compile a project composed of large codes which all were written in fortran language using Microsoft Visual Studio and Compiler was Intel Visual Fortran 11.1.038. Please note that this project have been already compiled using Compaq Visual Fortran and got the outputs well.

Problem is, the method to migrate from CVF to IVF works for some projects only while other projects are not giving outputs properly.

So, I have just tried to create a new project using the same codes and tried to run using IVF. When I was doing so,  i have got following errors. I have listed below errors for your reference and also I am seeking your guidance regarding with these errors.

Error    2     error #6631: A non-optional actual argument must be present when invoking a procedure with an explicit interface.   [PS_OUT]       
Error    3     error #6631: A non-optional actual argument must be present when invoking a procedure with an explicit interface.   [TS_OUT]       
Error    6     error #7836: If the actual argument is scalar, the corresponding dummy argument shall be scalar unless the actual argument is an element of an array that is not an assumed-shape or pointer array, or a substring of such an element.   [YTAB]    
Error    4    Compilation Aborted (code 1)    
Error    7    Compilation Aborted (code 1)

Also please note that I have got these error when I was performing Build.

Thank you.  

   

 

 

0 Kudos
TimP
Honored Contributor III
3,294 Views

FRESHIPALI R. wrote:

 

Error    3     error #6631: A non-optional actual argument must be present when invoking a procedure with an explicit interface.   [TS_OUT]       
Error    6     error #7836: If the actual argument is scalar, the corresponding dummy argument shall be scalar unless the actual argument is an element of an array that is not an assumed-shape or pointer array, or a substring of such an element.   [YTAB]    

These questions aren't closely related to the previous subject of the thread.

CVF didn't check for these errors when building without explicit interface between procedures in different source files.  ifort creates its own explicit interface when warn-interfaces is set.

If you got away with mis-matched numbers of arguments when you didn't check, you were lucky, and couldn't count on it continuing to work.

Suggestions for passing a scalar as an array of length one have been given earlier on this forum.  On Intel architectures, it might be viewed as cosmetic, but failure to do this could cause the program to fail on non-Intel-compatible platforms even if the compiler doesn't check.

0 Kudos
FRESHIPALI_R_
Beginner
3,294 Views

Thank you. Mr. Tim.

For the Error 3, I have found that there was some mismatched arguments in Calling Subroutine. By the way I got idea of resolving this error through referring one forum name A Non-Optional Argument? which was really helpful to me.

Now I am referring about passing a scalar as an array of length.

Once again thank you so much.

 

 

 

0 Kudos
Reply