- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Avoid any advice that asks you to avoid anything at any cost..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page