Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Fortran 90, is it impossible to refer to previously-declared variables in the declaration statement of a new variable?

In Fortran, is it possible for declaration statements for variables to refer to previously-declared variables? For example, when I try the following:

PROGRAM test3
  IMPLICIT NONE

  INTEGER :: a=2286
  INTEGER :: b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

I get a compile-time error message:

test3.f90:5.16:

  INTEGER :: b=a/3
                1
Error: Parameter 'a' at (1) has not been declared or is a variable, which
does not reduce to a constant expression

On the other hand, if I assign b to a/2 in a statement separate from the declaration of b, it compiles and runs fine:

PROGRAM test3
  IMPLICIT NONE

  INTEGER :: a=2286
  INTEGER :: b
  b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

which gives me the correct output:

2286         762

Why is this the case--that previously-declared variables cannot be included in declaration statements of new variables? Am I doing something wrong? Or is this just a "Fortran fact of life"?

Thank you very much for your time!

like image 1000
Andrew Avatar asked Jun 28 '11 16:06

Andrew


People also ask

Which of the following Cannot be used as variable in Fortran?

The words which make up the Fortran language are called reserved words and cannot be used as names of variable. Some of the reserved words which we have seen so far are "program", "real", "stop" and "end".

What is variable declaration in Fortran?

Declaring the type of a Fortran variable is done with type statements. It has the following form: type-specifier :: list. where the type-specifier is one of the following and list is a list of variable names separated with commas: INTEGER : the variables in list can hold integers.

How do you call a subroutine in Fortran 90?

Just like Fortran 77, the language Fortran 90 allows for two types of subprograms: (1) Functions, and (2) Subroutines. In general, there are two forms of subprograms: (1) Internal, and (2) External. Internal subprograms are those routines that may appear within the main program by making use of the CONTAINS statement.


2 Answers

Let me just add one more thing: Initializing a variable like this works in main programs and for parameters (well, you have to initialize them like this for parameters), but it can surprise you with its behaviour if you get too used to using it and start using it in subroutines and functions:

For instance, most of us would initially assume that this program:

program foo

   call bar
   call bar

contains

  subroutine bar
  integer :: i=3

      print '(A,I3)','At start of bar: i = ', i
      i = i + 1
      print '(A,I3)','At end of bar:   i = ', i
  end subroutine bar

end program foo

would print

At start of bar: i =   3
At end of bar:   i =   4
At start of bar: i =   3
At end of bar:   i =   4

--- but it doesn't. It prints

At start of bar: i =   3
At end of bar:   i =   4
At start of bar: i =   4
At end of bar:   i =   5

This is for "historical reasons", as things often are when they present behaviours which seem clearly wrong. Initializing a variable at declaration essentially turns this:

integer :: i

into

integer, save :: i = 3

and the initialization is done only the first time. That means the second time through, the variable remembers it's previous value (4) and increments that.

So my reason for writing this is basically to warn you not to get too comfortable initializing variables at declaration time. I recommend doing it for parameters, and in the main program (where you won't hit this issue since you only enter the main program once) and little else.

like image 85
Jonathan Dursi Avatar answered Jan 03 '23 23:01

Jonathan Dursi


The error message is pretty explicit. Initializers using in variable declarations have to be constant values. In your example, a is not a constant.

It should work like this:

PROGRAM test3
  IMPLICIT NONE

  INTEGER, PARAMETER :: a=2286
  INTEGER :: b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

because then a is a constant.

like image 38
talonmies Avatar answered Jan 03 '23 23:01

talonmies