horaceZettai
horaceZettai

Reputation: 33

Are Fortran named constants evaluated each time the containing module is used?

Say I define the parameter pi = -acos(-1.0) and save it in a module. When I use this module in another program, is the value of pi computed from the function ACOS each time?

If that's the case, is it better to define pi = -3.1415.... to whatever precision I require?

Upvotes: 3

Views: 182

Answers (2)

francescalus
francescalus

Reputation: 32396

If you have a named constant defined in a module then its value must be given by a constant expression. In a compile/execute module this constant expression will typically be evaluated when compiling the module itself, rather than when it is ultimately referenced.

Either way, there is no possibility for something using a module to affect the evaluation of the named constant's value in that module.

For the example of the question, ACOS(-1.0) is evaluated using whatever the default real kind is at the time of compiling. If this is changed to something like

module pidef
  use, intrinsic :: iso_fortran_env, only : piprec => real64
  implicit none
  real(piprec), parameter :: pi = ACOS(-1.0_piprec)
end module

then the constant expression uses the value of piprec in scope at that point. Being a constant expression every value must be well-defined by then. It will not be the case that something like

program piuse
  use, intrinsic :: iso_fortran_env, only : piprec => real32
  use pidef
  implicit none
end program

will somehow evaluate pi using real32. Equally there is no way to reference in the module's constant expression a variable defined globally later on, after the module is compiled.

Upvotes: 3

veryreverie
veryreverie

Reputation: 2981

No, parameters are calculated at compile time. The performance of the two methods should be identical.

Also, if you are wondering which of two options is faster, the answer is almost always "try it and see". If you care about your code running fast, you should use a code profiler to accurately time your code and work out what is slowing it down.

N.B. while the speed should be the same, there is the issue of precision. If you define pi using acos(-1.0) it will only be accurate to default single precision. If you want to define pi like this, you should use acos(-1.0_dp), where dp defines the floating-point precision you need.

Upvotes: 2

Related Questions