The problem here is with the argument a
of the function pow
. In the function the argument a
is (potentially) modified on the line
a=MOD(a*a,m)
The actual argument 10_8
when referencing the function is a literal constant which may not be modified. This is when your program fails. When you use print*,pow(j,i)
the j
is a variable which may be modified, and your program doesn't fail.
There is a lot of complicated stuff going on here, that I won't fully explain in this answer (you can search for other questions for that). One topic is argument association which explains why you are trying to modify the constant 10_8
. However, I'll say something about dummy argument intents.
The dummy argument a
has no intent specified. As you intend to use the value of the a
as it enters the function and you wish to (potentially) modify it an appropriate intent would be intent(inout)
. If you apply this, you should find your compiler complain about that assignment line.
Having no intent, such as in the case of the question, is an acceptible thing. This has certain meaning. That is, whether a
may be modified depends on whether the actual argument when referencing the function may. When the actual argument is 10_8
it may not; when it is j
it may.
The crucial thing is that it isn't the compiler's responsibility, but yours, to check whether the program is doing something here it shouldn't.
Now, you may not want to modify the actual argument j
even when you are allowed to. You have a couple of options:
- you can make a temporary local copy (and mark
a
as intent(in)
), which may be safely modified;
- you can make an anonymous modifiable copy of the input data using the
value
attribute.
You do this first with cur=pwr
. As an example of the second:
integer(kind=bigint) function pow(a,pwr)
implicit none
integer(kind=bigint), value :: a, pwr
pow=1
do while(cur>0)
if(mod(pwr,2)==1)pow=mod(pow*a,m)
a=MOD(a*a,m)
pwr=pwr/2
end do
end function
You now may even mark pow
as a pure function.
Finally, if using the value
attribute it is required that an explicit interface be available when referencing the function. With the module for the function this is the case here, but this is something to consider in more general cases.