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!
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".
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.
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.
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.
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.
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