Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Fortran resolve optional arguments and present statements during compile-time?

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!

like image 912
user3512099 Avatar asked Dec 20 '22 16:12

user3512099


1 Answers

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.

like image 76
High Performance Mark Avatar answered Jan 13 '23 11:01

High Performance Mark