Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does fortran function pass by const reference?

Tags:

fortran

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.

like image 701
andy90 Avatar asked Aug 31 '26 18:08

andy90


1 Answers

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?

  1. 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.

  2. 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.

like image 85
Robert Redl Avatar answered Sep 05 '26 02:09

Robert Redl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!