I'm learning how to use functions in fortran and I came across several cases which made me believe that fortran function pass the argument by const reference. When I say "pass by const reference", I'm saying it in C++ sense. I searched online and didn't find related documents. The code which makes me believe fortran functions pass arguments by const reference is as follows.
program try
implicit none
real sq
real a,b
write(*,*) sq(2)
a=2
write(*,*) sq(a)
end program
real function sq(x)
real x
sq=x**2
return
end
The output for this is
0.0000000E+00
4.000000
This result supports the idea that fortran functions pass arguments by reference, since sq(2) doesn't work. After this code, I put a new line x=x+1 inside the definition of sq. The code looks like
program try
implicit none
real sq
real a,b
write(*,*) sq(2)
a=2
write(*,*) sq(a)
end program
real function sq(x)
real x
x=x+1
sq=x**2
return
end
This code does compile, but when I run it, it gives the following error
forrtl: severe (180): SIGBUS, bus error occurred
Image PC Routine Line Source
a.out 00000001000014DB Unknown Unknown Unknown
a.out 000000010000144C Unknown Unknown Unknown
Stack trace terminated abnormally.
I guess I got this error because I can't modify the argument inside the function definition, which makes me believe that the argument is passed by const reference. The compiler I'm using is ifort 12.0.0. I'm running it on Mac OS X 10.6.8. Can anyone tell me whether my guess is true?
Update: According to the comment of @Jean, after modifying sq(2) to sq(2.0). The first example will work, the second one still gives the same error. The modified version of the first example is
program try
implicit none
real sq
real a,b
write(*,*) sq(2.0)
a=2
write(*,*) sq(a)
end program
real function sq(x)
real x
sq=x**2
return
end
The output is
4.000000
4.000000
I don't know why this simple modification will work. Hopefully someone can clarify for me.
As pointed out in the comments, you should use explicit interfaces. Then the compiler is able to check argument types. There are different possibilities to do that. For larger programs use modules, for smaller ones, you can include your procedure in the main program by using the contains keyword.
Here is a slightly modified version of your code:
program try
implicit none
real a,b
write(*,*) sq(2.0)
a=2
write(*,*) sq(a)
contains
real function sq(x)
real, value :: x
x=x+1
sq=x**2
return
end
end program
What's new?
the function is included in the main program with the contains keyword. When doing so, you don't have to declare sq like you did before in your third line. Also, the compiler can now check the argument type. Try to write 2 instead of 2.0 and see what happens.
You are right about the references. In Fortran arguments are passed by reference. If your argument is not a variable but just a number, then you can not change it within the procedure because it is constant. If you want variables to be passed by value, use the value keyword.
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