After a search without any result I want to ask you a question regarding subroutines containing optional arguments and how they are treated by the compiler (run time/compile time). Consider the following example program.
module CONTAINS_ABC
contains
subroutine ABC( a, b, c)
implicit none
real, intent(in) :: a
real, intent(in), optional :: b, c
if( present(b) )then ! PATH_B
write(*,*) 'Provide c'
else if( present(c) )then "! PATH_C
write(*,*) 'Provide b'
end if
! Do all the computations with a, b and c
end subroutine ABC
end module CONTAINS_ABC
program CALL_ABC
use CONTAINS_ABC
real :: aa, bb, cc
call ABC( a = aa, b=bb )
call ABC( a = aa, c=cc )
end program CALL_ABC
I wonder how the compiler treats subroutines with optional arguments in terms of optimization
. Does the compiler produce implicitly two interfaces for the subroutine FCN and chooses then the right one during compile time in the main program? Furthermore, is the present(b)/present(c) statement evaluated at runtime or during compile time?
In case I understand things right, the compiler might know that the first call to ABC leads to the path B, while the second call to ABC must lead to path C.
I ask this question, since I have a subroutine that is called million-million of times.
I want to avoid that during runtime the decision is made wether to go along path B or path C. It would be possible of course two write simply two subroutines, however, this would produce a lot of additional lines that would actually do the same thing.
Thank you all in advance for your help!
The Fortran standards are silent on pretty much every aspect of the implementation of the language other than the syntax and semantics. For example, people often think that Fortran passes arguments by reference but the standard only requires that programs behave as if arguments are passed by reference. Implementers are free to use pass-by-pixies if they wish and if they can thereby produce a convincing simulation of pass by reference.
That's just a long-winded introduction to telling you that how a particular compiler implements a language feature is, in general, compiler-specific. Implementation details are also know to vary from version to version of the same compiler.
I think that you are wrong to think that the presence of an optional argument will be checked at compile-time even if it is provable that it could be -- I just don't think that that is something that the current crop of compilers do. I expect the compiler to generate a single implementation of the subroutine with optional arguments. It does, after all, rest with the programmer to ensure that a procedure does not attempt to process absent optional arguments.
If you, the programmer, know that a procedure will be executed many times and if you suspect that different implementations, one with argument b
and without c
, one vice-versa, then it's on you to determine if separate implementations will be faster than one implementation with optional arguments. If you are concerned about code duplication you could always have yet a third procedure to implement the common code, and call it from both variants.
Equally, it is on you to inspect the assembler generated by your compiler to see just what your compiler (version) does with the variations in code that you write.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With