Suggest you habe a fortran module with a collection of mathematical constant like PI.
module constant_m
real, parameter :: PI = 3.1314_8
end module
Now you use this module in a function which calculate the circumcenter of a circle with given radius.
function U(r)
use constant_m
implicit none
real, intent(in) :: r
real :: U
U = 2*PI*r
end function
Will the expression 2*PI be evaluated a compile or runtime?
Lets check the generated assember code!
...
And you'll see only crap.
Let's start with an simpler example. Replace every real to integer. Truncate PI to 3, thats fair enough. And remove the "2*" expression. Somewhere in the assembler code are there must be the expression y=3*x.
Here it is:
gfortran --save-temps -O1 -c constants.F90 circle.F90
movl 4(%esp), %eax % Store the adress of r from stack pointer into eax
movl (%eax), %eax % Dereference adress and store value from r into eax
leal (%eax,%eax,2), %eax % eax = eax + 2*eax
The last line is the one. The compiler optimize the multiplicaton with 3 to an assembler instrctuin which performs a multiplication with 2 and an addition.
What we not see is a constant "3" in assember code. Or a assembler register filled with "3".
Lets add the "2*" and see whats happens.
movl 4(%esp), %eax
movl (%eax), %eax
leal (%eax,%eax,2), %eax
addl %eax, %eax
Only the last line is new. The compiler decide that x+x is more performance than 2*x. Cute.
Okay lets have some fun. We force the compiler to evaluate (2*PI) first. (2*PI)*r
And the resulting assembler code is the same HAHA.
Okay back to topic. We see that integer, parameter variables in modules are evaluated at compile time. Lets switch back to real.
Now the assembler code looks a litte bit more complicated:
flds .LC0@GOTOFF(%eax) % Load constant into floading point register
movl 4(%esp), %eax % Store value from r into eax
fmuls (%eax) % Multiply the constant with r and put the result back in eax
.LC0:
.long 1086918230 % The constand 2*PI
Now you can see a constant in assember as a 4byte iteger. Its only one constant, so I guess its 2*PI here.
This constant is loaded into a floting point register. The value from r is loaded into a second register. Then both get multiplyed. Thats all. Only a single multiplaction.
PARAMETER VARIABLES IN MODULE ARE EVALUATED AT COMPILE TIME! :D