Passing variables in FORTRAN

  • Fortran
  • Thread starter Milleniumeye
  • Start date
  • Tags
    Fortran
  • #1
Milleniumeye
2
0
TL;DR Summary
It is necessary to pass the value of a variable from one FORTRAN program to another.
I need to pass the value of a variable from one FORTRAN program to another. The main program carries out calculations with some numerical inputs a,b , I want to enter numerical values of variables in another program like
real*8 a, b
common/variables/a,b
a = 1.
b = 2.

How should I declare them in the main program and how should I compile the file?
This option resulted in an error:
error: unknown type name 'real'
 
Technology news on Phys.org
  • #2
That's a C compiler error. How are you compiling your FORTRAN?

Also, one program runs at a time - there is no way to pass variables between programs. Are you sure you don't mean subroutines or functions?
 
  • #3
Have the first program write the variables to a file and the second program read the file.
 
  • Like
Likes jedishrfu and FactChecker
  • #4
Or write a top level script that parses outputs from one program and calls another with data on the command line.
 
  • #5
phyzguy said:
Have the first program write the variables to a file and the second program read the file.
To extend this answer, you can either write the variable values in binary or as formatted character data. The binary approach preserves the value of the data better than the formatted character approach which may round the data depending on the precision you use.
 
  • #6
One could also write the data in a user defined environment variable to be read by the second program. It would have to be formatted character data.

This approach is good for a small number of variables vs a file approach which can handle large amounts of data.
 
  • #7
jedishrfu said:
To extend this answer, you can either write the variable values in binary or as formatted character data. The binary approach preserves the value of the data better than the formatted character approach which may round the data depending on the precision you use.
In FORTRAN, list directed writes and reads are a convenient way to pass data in a formatted file that can be easily read by a programmer or another FORTRAN program. That can really help in debugging. (See List-Directed I/O)
 
Last edited:
  • #8
Why are you trying to use "common" variables instead of the usual argument-passing mechanism for subprograms or functions?
 
  • Like
Likes Vanadium 50
  • #9
Milleniumeye said:
TL;DR Summary: It is necessary to pass the value of a variable from one FORTRAN program to another.

I need to pass the value of a variable from one FORTRAN program to another. The main program carries out calculations with some numerical inputs a,b , I want to enter numerical values of variables in another program
Your question isn't very clear. My thought is that you aren't used to the terminology used in Fortran programming. What I believe you are asking about is how to pass values from a Fortran main program to a subroutine or function. Each Fortran "program" will have a block of code like the following:
Fortran:
program CalcArea
<declarations>
<code>
end program CalcArea
Most Fortran programs other than the most trivial additionally include subroutines and/or functions that are called from the main program. The main program will often communicate with the subroutines or functions by passing parameters. This seems to me what you are asking about.

If that's the case, here's some example code in which the main program calls three separate subroutines -- one to get input from the user, another to do some calculations, and a third to output the results. The example, which I found here, https://web.chem.ox.ac.uk/fortran/subprograms.html, is a bit archaic in its style with everything in all caps, but it should give you an idea of what parameter passing looks like.
Fortran:
PROGRAM SUBDEM 
REAL A,B,C,SUM,SUMSQ 
CALL INPUT( A,B,C)
CALL CALC(A,B,C,SUM,SUMSQ)
CALL OUTPUT(SUM,SUMSQ)
END

SUBROUTINE INPUT(X, Y, Z)
REAL X,Y,Z
PRINT *,'ENTER THREE NUMBERS => '
READ *,X,Y,Z
RETURN
END

SUBROUTINE CALC(A,B,C, SUM,SUMSQ)
REAL A,B,C,SUM,SUMSQ
SUM = A + B + C
SUMSQ = SUM **2
RETURN
END

SUBROUTINE OUTPUT(SUM,SUMSQ)
REAL SUM, SUMSQ
PRINT *,'The sum of the numbers you entered are: ',SUM
PRINT *,'And the square of the sum is:',SUMSQ
RETURN
END
 
  • #10
I seem to remember using the COMMON command. That sets aside common memory which each subroutine or function writes and reads. IIRC, it's a blank, unformatted area of memory and the variables need to be defined carefully so the routines all know which location is which.
 
  • #11
Is the OP still here? @Milleniumeye , can you comment on the suggestions you've received?
 
  • Like
Likes Vanadium 50
  • #12
Yes to @sophiecentaur.

The common block was a way to share variables across the program space. It's akin to a global struct used in C programming.

pros:
- improved program speed since they weren't needed in the subroutine call.
- common block names had to be the same wherever used
- common block variable names could vary as could their datatype but the programmer needed to know what they were doing (changing datatype was considered a very bad coding practice)

cons:
- common variable names could be different or datatype could be different which led to hidden bugs

Some of the errors I saw:
- large common block programmer forgot to list a variable shifting the variables over one place
- similarly someone adding a new variable and forgetting to change all common blocks
- one or more variable name were changed and implicit or explicit datatype rules changed them from integer to real or vice versa

I saw these used in old Fortran programs used for turbine modeling.
 
  • Like
Likes sophiecentaur
  • #13
jedishrfu said:
pros:
...programmer needed to know what they were doing
Some would call this a "con".

In some ways, it was more like a union than a struct. As such, when things went wrong, they went spectacularly wrong.

Like many features in many languages, common blocks got a bad rep from overuse and people coding before thinking. "Hey, let's just put everything into one giant common block!" is not a good idea.
 
  • Like
Likes sophiecentaur and jedishrfu
  • #14
But the common block was a feature for the times. Subroutine calls in FORTRAN were not recursive. Subrourine calls did not pass by value. Arguments often used one of several CPU registers for their address.

Using common blocks allowed for faster processing as indexing was somewhat slower.

It was a dangerous time for programming. In one of my programs, I recall passing a numerical constant, 3 ( a 2=pendown and a 3=penup ) to third party subroutine. The subroutine had an obscure side-effect and changed the argument value to a 2 and I got the craziest looking plots. Basically everywhere I used a 3 now became a 2.

It was issues like this that drove language design to be more protective of data constants.
 
Last edited:
  • Like
Likes sophiecentaur and FactChecker
  • #15
jedishrfu said:
But the common block was a feature for the times. Subroutine calls in FORTRAN were not recursive.
It depended on the compiler and the care taken by the programmer. Using VAX Fortran-77, one could do recursion and reentrance quite well as long as one took care to keep ones paws off locally declared variables.

I would usually allocate a hunk of dynamic memory and pass its address in as a parameter. The subroutine could treat that parameter as a structure or as an array. There was no language-provided guarantee that this would work as expected, but it did work quite reliably and well.
'
There was a language issue that a subroutine could not directly call itself. Within the subroutine, the subroutine name is used to denote the function return value. It can be used on the left hand side of an assignment statement, not on the right hand side of a call or in a function invocation. So you would cheat and call a jacket subroutine which could then call you back.

I would often use the AST (Asynchronous System Trap) control block (ACB) as the dynamically allocated storage area. This made integration with system services quite convenient and acceptably re-entrant.

On VAX or Alpha, language extensions %val, %ref, %descr and %loc could be used to populate the argument list in the proper way to make this work smoothly.

It has been decades since I did this for a living.

I avoided common blocks. Real quiche-eaters can write Pascal in any language.

jedishrfu said:
The subroutine had an obscure side-effect
Datatrieve on VAX was a reporting language that allowed function invocations but not assignment statements or conditional code execution. This made it impossible to take context-specific actions. But if one invoked a function with purpose-built side effects, much became possible!
 
Last edited:
  • Like
Likes BvU
  • #16
My FORTRAN experience was first with Fortran-IV and later with Honeywell Fortran-Y which was IV with some added features like the CHARACTER datatype and freeform coding. (no more punch card limitations ie code col 7 thru 72 with line nos in cols 1-5, continuation indicator col 6 and sequence nos in cols 73-80).

Freeform had some gotchas:
- a C in column 1 made the line a comment
- woe to the programmer who wrote CALL, CHARACTER, COMPLEX or COMMON ... starting in column 1 many compile time errors would result

In this dialect of FORTRAN:
- calls to subroutines were all call by reference (if you passed a constant its value could be changed)
- recursion was not a feature (recursive factorial would result in an endless loop)
- no stack
- constants were stored with variables and were mutable
 
  • Like
Likes dlgoff
  • #17
I suppose the OP isn't coming back, so we can all reminisce about the Good Old Days.

Computed GOTO anyone? Talk about job security!
 
  • Like
Likes hutchphd and Astronuc
  • #18
Vanadium 50 said:
I suppose the OP isn't coming back, so we can all reminisce about the Good Old Days.
My first exposure was pre-Fortran I. Since there is no Roman numeral for zero, it was just called Fortran. We didn't have those new-fangled Hollerith cards -- we had to chisel our code into clay tablets that were then baked for XII hours. The tablet readers read the tablets and then glued wires to specific junctions in the computing machine (which was powered by oxen chained to arms radiating from a spindle). Talk about turn-around times! If your code had no bugs (literal insects that got baked into the tablets), you might get results back by the next full moon.
 
  • Haha
Likes FactChecker and berkeman
  • #19
Clay? You had clay? You were lucky!
And oxen? Pure luxury! :smile:
 
  • Haha
Likes FactChecker
  • #20
Mark44 said:
we had to chisel our code into clay tablets that were then baked for XII hours.
And when the Internet came along, you uploaded the tablets to the cloud via pack trains of llamas. Or were they alpacas?
 
  • Haha
  • Like
Likes hutchphd and Mark44
  • #21
Vanadium 50 said:
Clay? You had clay? You were lucky!
And oxen? Pure luxury! :smile:
Shades of the Four Yorkshiremen...
 
  • Haha
Likes sophiecentaur
  • #22
The FORTRAN Yorkshiremen.
 
  • Like
  • Haha
Likes jtbell and Mark44
  • #23
Vanadium 50 said:
The FORTRAN Yorkshiremen.
Wearing frocks?
 
  • #24
Vanadium 50 said:
The FORTRAN Yorkshiremen.

sophiecentaur said:
Wearing frocks?
Wrong Monty Python skit. The Four Yorkshiremen were at their club, smoking cigars and drinking Château de Chasselas, comparing notes about how things were when they were young. If you haven't seen it, search for "Four Yorkshiremen" on Youtube.
 
  • #25
Try again. ‘Trans’ = frocks.
 
  • #26
Vanadium 50 said:
The FORTRAN Yorkshiremen.
Shouldn't that be the FORTRAN IV Yorkshiremen?
 
  • Haha
Likes Vanadium 50

FAQ: Passing variables in FORTRAN

What are the different ways to pass variables in FORTRAN?

In FORTRAN, variables can be passed to subroutines and functions in several ways: by value, by reference, and using pointers. By default, FORTRAN passes variables by reference, meaning that the address of the variable is passed, allowing the subroutine to modify the original variable. Alternatively, you can pass variables by value using the 'value' attribute, which creates a copy of the variable.

How do you pass arrays to subroutines in FORTRAN?

Arrays can be passed to subroutines in FORTRAN by simply specifying the array name in the argument list. The subroutine can then access the elements of the array using the same indexing as in the calling program. It's important to ensure that the array dimensions are correctly declared in the subroutine to avoid any runtime errors.

What is the difference between passing variables by reference and by value?

Passing by reference means that the address of the variable is passed to the subroutine, allowing the subroutine to modify the original variable. In contrast, passing by value means that a copy of the variable is passed, so any modifications made within the subroutine do not affect the original variable. This can be useful when you want to protect the original data from being altered.

Can you pass derived types in FORTRAN, and how?

Yes, you can pass derived types in FORTRAN. To do this, you simply declare the derived type and then pass it as an argument to a subroutine or function. The subroutine or function can then access the components of the derived type using the dot operator. It's important to ensure that the derived type is defined before it is used in the subroutine or function.

What happens if you pass a variable that is not compatible with the expected type?

If you pass a variable that is not compatible with the expected type in FORTRAN, you may encounter a runtime error or unexpected behavior. The compiler may issue a warning or error during compilation if type checking is enabled. To avoid such issues, it's essential to ensure that the variable types match the expected types in the subroutine or function signature.

Similar threads

Replies
59
Views
10K
Replies
4
Views
2K
Replies
4
Views
2K
Replies
5
Views
1K
Replies
2
Views
2K
Replies
8
Views
1K
Replies
4
Views
2K
Replies
16
Views
2K
Back
Top