@device(PostScript)
@make(report)
@LibraryFile(stable)
@DefineFont(HeadingFont,
        P=<RawFont "NewCenturySchlbkBoldItalic">,
        B=<RawFont "NewCenturySchlbkBold">,
        I=<RawFont "NewCenturySchlbkBoldItalic">,
        R=<RawFont "NewCenturySchlbkRoman">)
@Counter(MajorPart,TitleEnv HD0,ContentsEnv tc0,Numbered [@I],
          IncrementedBy Use,Announced)
@Counter(Chapter,TitleEnv HD1,ContentsEnv tc1,Numbered [@1. ],
          IncrementedBy Use,Referenced [@1],Announced)
@Counter(Appendix,TitleEnv HD1,ContentsEnv tc1,Numbered [@I. ],
          IncrementedBy,Referenced [@I],Announced,Alias Chapter)
@Counter(UnNumbered,TitleEnv HD1,ContentsEnv tc1,Announced,Alias 
           Chapter)
@Counter(Section,Within Chapter,TitleEnv HD2,ContentsEnv tc2,
          Numbered [@#@:.@1 ],Referenced [@#@:.@1],IncrementedBy
          Use,Announced)
@Counter(AppendixSection,Within Appendix,TitleEnv HD2,
          ContentsEnv tc2,
          Numbered [@#@:.@1 ],Referenced [@#@:.@1],IncrementedBy 
          Use,Announced)
@Counter(SubSection,Within Section,TitleEnv HD3,ContentsEnv tc3,
          Numbered [@#@:.@1 ],IncrementedBy Use,
          Referenced [@#@:.@1])
@Counter(Paragraph,Within SubSection,TitleEnv HD4,ContentsEnv tc4,
          Numbered [@#@:.@1 ],Referenced [@#@:.@1],
          IncrementedBy Use)
@modify(CopyrightNotice, Fixed -1 inch, Flushright)
@Modify(Titlebox, Fixed 2.5 inches)
@Modify(hd1, below .2 inch, facecode B, size 24, spaces kept)
@Modify(hd2, below .2 inch, facecode B, size 18, spaces kept)
@Modify(hd3, below .2 inch, facecode B, size 12, spaces kept)
@Modify(Description, Leftmargin +20, Indent -20)
@Modify(Tc1, Above .5,  Facecode B)
@Modify(Tc2, Above .25, Below .25, Facecode R)
@Modify(Tc3,Facecode R)
@Modify(Itemize,Above 1line,Below 1line,Spacing 1,Spread .25)
@Modify(Example, size 11)
@Style(Font NewCenturySchoolBook, size 11)
@Style(Spacing 1.1, indent 0)
@Style(leftmargin 1.0inch)
@comment (@Style(justification no)
@Style(BottomMargin 1.5inch)
@Style(ChangeBarLocation Right)
@Style(ChangeBars=off)
@pageheading(immediate)
@pagefooting(left="MIT Project Athena", 
center=@value<page>, right="Revision C September 1, 1987")
@Blankspace(1 inch)
@begin(MajorHeading, Flushright, size 36, FaceCode b, below .3)
Essential Fortran
@end(Majorheading)
@blankspace(.75 inch)
@begin(flushright, Font HeadingFont, FaceCode R,  size 14)
Linda B. Merims
MIT Project Athena
Revision C
September 1, 1987
@end(flushright)
@copyrightNotice(Massachusetts Institute of Technology)
@set(page=0)
@newpage

@section(Introduction)
@p(Essential Fortran) shows you how to 
create a short sample Fortran program, compile it,
and then run the compiled program.
It is intended for students who must run Fortran programs
as part of their coursework and who want to get started 
as quickly and simply as possible.  @p(Essential Fortran's) emphasis is on
following the example by rote; there is little explanation of what
you are doing.  The latter part of the document
contains more advanced information on run-time debugging, linking, and file
I/O.  @p(Essential Fortran) does not
teach you the Fortran language.  
For more information on this and any of the steps shown here, see the
Athena documents mentioned in the text and in the section
labelled "For More Information."

@section(Antecedents)

We assume that you know all of the following.
If you are a student in a class, your instructor should provide you
with some of this information.  You probably specified your username 
and password yourself.
@begin(format, leftmargin +3)
@tabclear
@tabset(2.5 inches)
your username:@\a 3-8 letter "name" that identifies you to the system
your password:@\a short password to keep your username private
cluster door combination:@\the numeric key to unlock the cluster door
@end(format)

We also assume that you know how to login to a Unix system and
that you know the few extras 
involved in using a workstation.
If you need to learn more about how to get started with Unix or
how to use a workstation, see @p(Athena Workstations), and the @p(Athena Reference Card).  These are 
available in the Athena clusters.

@section(Creating the Fortran Program)

Once you have logged in, your first step is to
type your Fortran program into a @b(file).  (The assumption is that
you have already written the program out longhand and you just
need to type it into a computer file.)

To illustrate what it is like to create a Fortran program, compile and
execute it, we will use the following small program that converts
fahrenheit temperatures to centrigrade:
@begin(example, size 9)
C
C   Convert Fahrenheit temperatures to Centigrade: C = 5/9 (F - 32)
C
C234567----------------------------------------------------------------|------

      real  ftemp, ctemp

      print *, 'Type in a Fahrenheit temperature, then press RETURN'
      read  *, ftemp

      ctemp = (5.0/9.0) * ( ftemp - 32.0 )

      print *, ftemp, 'Fahrenheit is', ctemp, 'Centrigrade'
      print *, 'Exiting.  Bye.'
      end
@end(example)

To type your program into a file,
you call up the @b(emacs text editor) and give it a @b(filename)
to use.  You can name your files anything you like.  However, all
Fortran program files @b(MUST) be suffixed with a @b(.f) "file type."
If you don't give it a .f type, whenever you try to compile the program
it will always fail with the message, "ld:@i(filename):Bad magic number."

The file will be named ftoc.f.

@subsection(Starting Emacs)
@paragraph(Emacs on a Workstation)
First, you need to start @i(emacs) with a
@b(&) as the last character on the command line:
@begin(format, leftmargin +3)
workstation% @b(emacs  ftoc.f  &)
@end(format)
If you don't use the @b(&), you won't be able to use your original
window for anything until you leave emacs.
After you hit the RETURN key, Unix will print a message which looks
like this:
@begin(format, leftmargin +3)
@b([2] 10759)
@end(format)
Both numbers will be different each time; these are simply Unix's way of
letting you know that your emacs has been started.

Once your emacs has started a small flickering box will appear near the
mouse cursor.  This means that emacs is ready for you to choose
the size and location of the editing window.

To choose the location of your window, move the 
mouse cursor to where you want the upper-left-hand corner
of your emacs window to be and press a mouse button.

@begin(itemize)
Press the left mouse button to select a small, 24-line window
which resembles a timesharing emacs screen.

Press the right mouse button to select a large emacs window.
@end(itemize)

Pressing the center button on a VAXstation mouse, or both buttons on
an RT PC mouse, and dragging the mouse creates a variable sized window.

Once the emacs window appears, move the mouse cursor inside the
emacs window.  Emacs won't see anything that you type if the mouse cursor is
outside the emacs window.

The emacs window looks like the one shown below.
Everything above the line is a "blank page" that you can fill up with
text.  The line shows emacs status information.  If emacs has any questions
it will prompt you for answers at the bottom of the screen.  If you 
chose to use a large window, the "blank page" area above the line will be 
much larger.

@subsection(Fortran Format)
With this and all Fortran programs, you need to be careful about which
columns you put things in.  If you violate the rules, the errors that
result are usually copious, obscure, and hard to diagnose correctly.
Notice below how the programmer uses a comment card to help her line
things up.  The screen is 80 columns wide (like an old data card).

@begin(format)
--------------------------------------------------------------------------------------
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|@>|
|--**-Emacs: ftoc.f---------------------------------------------(Fundamental)----All-----|
| (New file )@>|
--------------------------------------------------------------------------------------
@end(format)
@newpage
This is the format to follow:  
@begin(description, spread 0)
@b(Columns@\What it contains)

1@\If a C is present, for "comment," the rest of the line is ignored.

2-5@\Fortran statement numbers.

6@\If not blank, this card is a continuation of the previous card.

7-72@\Program statements, indented as necessary.

73-80@\@b(MUST) be left blank.  Fortran ignores them.
@end(description)

@subsection(Typing in Text)
Type in the fahrenheit to centrigrade program as shown below.
Be sure to move the mouse cursor into
the emacs window.

@begin(format)
@tabset(+.5inches)
--------------------------------------------------------------------------------------
|C@>|                                                                   
|C@\Convert Fahrenheit temperatures to Centigrade: C = 5/9 (F-32)@>|    
|C@>|                                                                   
|C234567--------------------------------------------------------------|----@>|  
|@>|                                                                    
|@\real ftemp, ctemp@>|                                            
|@>|                                                                    
|@\print *, 'Type in Fahrenheit temperature, then RETURN'@>|       
|@\read ftemp@>|                                                   
|@>|                                                                    
|@\ctemp = (5.0/9.0) * (ftemp - 32.0)@>|                           
|@>|                                                                    
|@\print *, ftemp, 'Fahrenheit is', ctemp, 'Centigrade'@>|         
|@\print *, 'Exiting.  Bye.'@>|                                    
|@\end@>|                                                          
|@>| 
|--**-Emacs: ftoc.f---------------------------------------------(Fundamental)----All-----|
| (New file )@>|
--------------------------------------------------------------------------------------                                                                   
@end(format)

@begin(description)
@b(To enter text)@\Just start typing.  When you get to
the end of the line, press the RETURN key, just as you
would on an electric typewriter.

@b(Blankspace)@\Use the SPACEBAR to make blanks.  In
@i(emacs), there is a difference between a blank (made
with the SPACEBAR) and nothing at all.

@b(Blanklines)@\Make blank lines just as you would on
a typewriter, press the RETURN key an extra time.

@b(Typos)@\If you make a mistake while typing along, use
the DELETE key at the upper right of the main keyboard
(sometimes labeled <--) to backup and fix the mistake.
@end(description)
@newpage
@subsection(Fixing Text)
To edit existing text (fix typos, add or delete words or
lines, etc.), you move the @b(cursor) around the "page" until
it points to where you want to make a change and then you
enter a command.
@begin(description)
@b(Move the cursor)@\You move the cursor with the arrow
keys at the right of the keyboard.  Notice how the cursor
"wraps around" when you go over the end of a line.  Please
note that on some terminals there is a <-- delete key and
a <-- arrow key.  They are different.

@b(Inserting letters)@\Move the cursor to where you want the
new characters.  Type them.  The rest of the text shifts
over to accommodate them.

@b(Inserting lines)@\Move the cursor to where you want the
new line to be.  Press RETURN.  A new line will open up.
You may have to move the cursor one spot to the beginning
of the new line.

@b(Deleting letters)@\Move to just @i(after) the character you
want to remove.  Press the DELETE key.

@b(Deleting lines)@\You can delete a whole line by just
typing enough DELETEs to devour it. Alternatively, move
the cursor to the beginning of the line, hold down the
CTRL key (lower left of the keyboard), and while still holding
it down, press k.  Press CTRL-k again to get rid of the
space the line occupied.
@end(description)

@subsection(Exit Emacs)
To leave @i(emacs), type @b(CTRL-x) followed by a @b(CTRL-c).
Hold down the @b(CTRL) key at the lower left of the keyboard
while you press @b(x).  Release the @b(x) key and (while
still holding down the @b(CTRL) key) press the @b(c) key.
At the bottom of the screen you'll see:
@begin(format, leftmargin +3)
Save file /mit/user/ftoc.f? (y or n)
@end(format)
Nothing you have done is permanent until you type @b(y) for yes
to this question.

If you reply @b(n) for no, emacs will ask you another question:
@begin(format, leftmargin +3)
1 modified buffer exists, do you really want to exit? (yes or no)
@end(format)
A @b(yes) answer to this question will cause all your changes
to be thrown away.

Answer @b(no), and emacs will neither save your file nor will it
exit.  It will wait for you to enter more text, or to type another
emacs command.

For more information on emacs, see the Athena documents
@i(Essential Emacs) and its accompanying @i(Emacs Quick
Reference) card, available in most Athena terminal clusters.
@newpage
@section(Compiling the Program)
The next step is to use a @b(compiler) to translate the
Fortran ftoc.f @b(source file) that you can read into
the @b(binary file) form that the machine can understand.  This
is called "compiling a program." The Unix Fortran compiler
is called @p(f77).  It usually takes several 
tries--perhaps many--to successfully
compile a program because the compiler will find mistakes in
the program.  Here is a first try at compiling the file ftoc.f:
@begin(format, leftmargin +3, size 8)
@tabclear
@tabset(3.25 inches)
yourhost% @b(f77 ftoc.f)@\<--run f77 on the ftoc.f file
ftoc.f:@\<--compiler starts sending messages of its progress
   MAIN:
Error on line 9 of ftoc.f: bad format descriptor@\<--compiler finds error


Error.  No assembly.@\<--compiler finishes without making a binary file
yourhost%
@end(format)
The @i(f77) compiler found an error in line 9 of the program, printed
a message, "bad format descriptor," and then quit.  The "Error.  No
assembly." message means that @i(f77) did not bother to make a 
machine-readable binary file because it wouldn't have worked.

You should now look at line 9 of your source program in ftoc.f
with the @i(emacs) text editor to see what could be wrong.

@section(Debugging)

Whenever you debug a program there are two main questions
to answer: @p(where) did the error occur and @p(what) was
the mistake.

Fortran @i(f77) compiler error messages tell you the line number where
it found the error.  But how, when there is more than just a few lines,
do you find this line in the original file, short of counting them with
your finger?

@subsection(Emacs Editor)

You can get the @i(emacs) editor to go directly to a particular line if
you know its line number.  Call up emacs with the file ftoc.f as you
did when you created your file.  Don't forget the @b(&) at the end of 
the emacs command.
As always when you start @i(emacs)
there will be a short pause, and then ftoc.f is displayed.

Now, tell emacs to go to line number 9 as follows:

@begin(enumerate, above 0 line, below 0 line,spread 0)
Press the @b(ESC) key.  You may have to hunt for it. It is on the row
of buttons across the top.
It is the F11 key or the key marked ESC.

Press @b(x).  Emacs will prompt M-x at the bottom of the
screen.

Now type out: @b(goto-line), and press RETURN.  Emacs
will then ask you @i(Goto line:) and you should type
the number @b(9) as your answer, and press the RETURN
key.  Emacs will move the cursor to the first character
of line number 9.

@end(enumerate)

Your screen will look like this:

@begin(format)
@tabset(+.5inches)
--------------------------------------------------------------------------------------
|C@>|                                                                   
|C@\Convert Fahrenheit temperatures to Centigrade: C = 5/9 (F-32)@>|    
|C@>|                                                                   
|C234567--------------------------------------------------------------|----@>|  
|@>|                                                                    
|@\real ftemp, ctemp@>|                                            
|@>|                                                                    
|@\print *, 'Type in Fahrenheit temperature, then RETURN'@>|       
|@\read ftemp@>|                                                   
|@>|                                                                    
|@\ctemp = (5.0/9.0) * (ftemp - 32.0)@>|                           
|@>|                                                                    
|@\print *, ftemp, 'Fahrenheit is', ctemp, 'Centigrade'@>|         
|@\print *, 'Exiting.  Bye.'@>|                                    
|@\end@>|                                                          
|@>| 
|--**-Emacs: ftoc.f---------------------------------------------(Fundamental)----All-----|
| (New file )@>|
--------------------------------------------------------------------------------------                                                                   
@end(format)

The error message read, "Error on line 9 of ftoc.f:  bad format
descriptor." Line 9 is the @b(read) statement.  You must now puzzle out
what the error message means.  "Bad format descriptor" means that
@i(f77) doesn't like something about the format part of the read
statement.  The format part of a read statement is nearly always the
next thing on the line after the word "read." It tells Fortran what the
output should look like (how it should be spaced, where to put the
decimal point, etc.) In this case,  the * ("use your default formatting
rules") was left out by mistake.  Fortran is having trouble figuring
how what an "ftemp" format should be, not realizing it is a variable,
not a format.

To fix this error, you must type the "*, " in with @i(emacs).  Move the 
cursor with the arrow keys to the "f" of "ftemp" and type the "*, ".
To exit @i(emacs), type CTRL-x CTRL-c.

@subsection(Hardcopy Output)

It is often much easier to debug a program off a paper copy;  you
see more of the program at once.  To produce a line-numbered paper
copy of your source program, type:
@begin(format, leftmargin +3)
host%  @b(cat -n @p(filename.f) | lpr)
@end(format)
The "cat -n" lists the file out line-numbered.  The "lpr" sends it
to the default printer for your cluster.  Don't forget the
@b(|) or it won't work.  You won't see
anything on the terminal screen.  Look for your username
on the front page of the output.  When you know the problem,
fix it with @i(emacs).  See @i(Printing from an Athena Workstation) for more information on @i(lpr).

@subsection(Another Technique)
Because emacs opens a new window on your workstation, you are able
to use the original login window that you typed the @i(emacs) 
command in for other
tasks.  You can use the @i(cat -n) command described above
to display your line-numbered Fortran program in this window.  To have 
your program
displayed in your Unix window one screen at a time, move the mouse 
cursor to this window and type:
@begin(format, leftmargin +3)
host% @b(cat -n @p(filename.f) | more)
@end(format)
If your program won't all fit on one screen, @i(more) will stop
when the screen fills up.  Hit the space bar to see the next screen 
of your program.  Be sure to move the mouse cursor back to the emacs 
window when you are finished reviewing your program.

@subsection(Rules of Thumb)
It takes practice and experience to learn how to debug.
Most errors are not so straight-forward. 
"Appendix A" is an alphabetic list of most of @i(f77)'s compiler
error messages along with a short explanation of what specific
problem causes the error.
After a while, you will become quite adept at interpreting error
messages.  You will be able to 
just glance at most messages and see the real mistake.
Here are a few guidelines on debugging:
@itemize[
Accept that @i(there really
is something wrong) with your program.
Don't insist that the compiler is
making a mistake.

Work from the top down.  Often later error messages are
just secondary effects of earlier errors.  Fix the first error,
and the rest may disappear.

Study the error message.  Look for a keyword
that rings a bell in your head to isolate which piece of the statement
may be causing the trouble.  If none of the words sound familiar,
look them up in your Fortran book's index. 
In the example above, the keyword was "format."  Compare what you have to
examples in your Fortran book.  If necessary, go character-by-character.
A single comma in the wrong place can be fatal.

@multiple{
Like a doctor diagnosing a
patient's symptoms, be a little open-minded and skeptical about
what the compiler tells you.  A patient who has been playing tennis
may come in asking for codeine for a sore arm--when they
may actually be experiencing angina.
Compilers are like that, what they complain about is
not always what's really wrong, just sort-of.

Error messages only tell you how the real problem manifested itself
as a symptom.  If you get error messages complaining about bad arrays
and you don't @I(have) any arrays, it means that you've got something
that, because of an error, @i(looks) like an array.

Error messages only
tell you when the compiler @i(first noticed) something was wrong.
It may be that there is nothing wrong with the statement itself,
but there could be something wrong with the statement immediately
before it, or even earlier.  This may just be the first place that
the consequences of the mistake show up.
}
@end(itemize)

@newpage
@section(A Successful Compilation)

To compile the ftoc.f program again:
@begin(format, leftmargin +3, size 9)
@tabclear
@tabset(3 inches)
yourhost% @b(f77 ftoc.f)@\<--compile again
ftoc.f
   MAIN:
host%@\<--no news is good news.  no compile errors found
@end(format)

When there are no serious errors, only warnings, the @i(f77) compiler
produces a new output file containing the compiled version of the ftoc
program.  This @b(binary file)
is what you run to actually execute the ftoc program.  You may also
hear binary files referred to as "executable images,"
and, occasionally, "load modules."
The binary file will, by default, be named @b(a.out).

You can get @i(f77) to name the binary file something different.
You will have to begin doing this when you have more than one program
file because whenever you @i(f77) a file it will overwrite
the existing a.out.  When
you compile the program, add the @b(-o @p(filename)) option.  This
tells @i(f77) to call the output file @i(filename) instead of
a.out.  For example:
@begin(format, leftmargin +3)
yourhost% @b[f77  -o ftoc  ftoc.f]
@end(format)
will produce a binary called just ftoc.  (This follows Unix
naming conventions.)  Notice that the "-o ftoc" comes @i(before) the
ftoc.f file.  

To see what files you have, use the Unix @p(ls) command (for "list"):
@begin(format, leftmargin +3)
yourhost% @b(ls)
a.out  ftoc.f  ftoc.o
@end(format)
(The ftoc.o file is an intermediate version of your program that
@i(f77) produces called an @b(object) file.  You can ignore it for now.)

The Athena document @i(Athena Workstation) explains more about Unix file maintenance commands.
@newpage
@section(Executing the Program)

After a "clean compile," you are ready to actually execute your
program and convert some fahrenheit temperatures to centigrade.
To execute any program, you type the name of its binary file--in
this case a.out--just as though it were another Unix command:

@begin(format, leftmargin +3, size 9)
@tabclear
@tabset(4 inches)
yourhost% @b(a.out)@\<--type:  a.out  and press RETURN
Type in a Fahrenheit temperature, then press RETURN@\<--program prints instructions
32@\<--you type in a number
32.0000  Fahrenheit is  0.0000  Centrigrade@\<--program prints results
Exiting. Bye.@\<--and exits
yourhost%
@end(format)

Things may not go this smoothly.  Even though it "compiled cleanly,"
the program may still have so-called @b(run-time) errors.

@section(Run-Time Debugging)

@b(Run-time) errors are not errors in syntax, but errors in logic
that the compiler cannot check.  They only show up when you try
to execute the program.  If you are @i(un)lucky, they do not show
up at all.  Run-time
errors are hard to diagnose.
There are very few run-time error messages, so it is hard to
tell @i(what) went wrong; and the Unix system
does not tell you in which statement an error occurred, so
it is also hard to tell @i(where) it went wrong.  "Appendix B" lists
such run-time error messages as there are, and we will show you
one way to find out the line number where an error occurred.

Run-time debugging is a large topic.  Run-time errors manifest themselves
in myriad ways.  We cover only the most obvious problems here.

@subsection(Typical Problems)

When you run a program, you usually see one of four things:

@begin(itemize)
Nothing happens for a @i(long) time.
You don't get back a system prompt indicating
that execution has finished, you don't get anything.   This usually
means one of two things is happening:
@begin(enumerate)
You have a @b(read) statement that is waiting for you to type
something and press RETURN.  You didn't precede it with a @b(write)
statement to tell you what to type.

Your program is infinite looping.  Kill it with a CTRL-C. 
You can find out where problems are by using the @i(dbx) 
debugger and the step-through technique shown below.  
@end(enumerate)

Your program starts spilling copious output at you and won't stop.
The output looks repetitious.  This usually means your program is
infinite looping.  Kill it with a CTRL-C.  Notice which @b(write)
or @b(print) lines keep repeating as they show indirectly which loop's
control variable or which @b(if-then-else) has gone awry.

Nothing really bad happens.  There are no error
messages, you just don't get the results you
expect.  The only way to solve this is to trace the execution
of the program:  either by adding print statements, or by using
the @i(dbx) symbolic debugger described below.

When you run the program, you get a message which ends in the
phrase "@i(core dumped.)"
Your program has encountered an error so severe that the Unix
system has terminated its execution.  In the vernacular, your
program has "bombed" or "died."  The "core dumped" means specifically
that Unix has created a file called @p(core) in the current directory
that is a hex core dump of your program when it died.  Experienced
programmers can examine core dumps to find out what went wrong with a
program, but it is not an easy thing to do.  The main thing to realize
is that the @i(core) file takes up a great deal of file space.  You
will want to delete it unless you have a purpose in mind for it.
@end(itemize)
The first two types of run-time errors are easier to find because
the incorrect program output gives clues as to what went wrong and
where it happened.  The last two groups of run-time errors are more
difficult to find since the program output only tells you that something
went wrong.  There is no message telling you @i(where) the problem is.
Using a program called a @p(debugger) can help you find out more
about where runtime errors are happening.
@newpage
@subsection(Using a Debugger)

Here is a Fortran program that has several mistakes that are going
to cause runtime errors:
@begin(example,size 8)
 1 C                                           2
 2 C   Program to solve quadratic equation:  ax  + bx + c
 3 C
 4 C               ---------
 5 C          +   / 2
 6 C       -b - \/ b  - 4ac
 7 C   x = -----------------
 8 C              2a
 9 C
10 C234567*********************************************************************
11 C Declarations
12
13        real  a, b, c, x1, x2, underradical
14
15 C Ask for initial values from user, then read what he typed
16
17        print *, 'Type in a b and c separated by blanks, then hit RETURN'
18        read  *, a, b, c
19
20 C Now go ahead and compute values
21
22        underradical = ( b**2 ) - ( 4 * a * c)
23        x1 = ( -(b) - (sqrt(underradical)) )  /  ( 2 * a )
24        x2 = ( -(b) + (sqrt(underradical)) )  /  ( 2 * a )
25
26 C Print results
27
28        print *, 'The two roots are:', x1, x2
29      
30 C And leave
31
32  200   print *, 'Exiting.  Bye.'
33        end
@end(example)

This program calculates the roots of a quadratic
equation.  You may be able to see the problem immediately.  
In trivial programs
such as this, that is often true.  But you will need the techniques
shown below when you have a program
with dozens of statements.

The program compiled cleanly:
@begin(format, leftmargin +3)
host%  @b(f77  quad.f)
quad.f:
   MAIN:
host%
@end(format)
When executed on a VAXstation, the following occurred:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inch)
host% @b(a.out)
  Type in a b and c separated by blanks, then hit RETURN
@b(0 5 7)@\<--user replies to query
*** Arithmetic Exception: Floating divide by zero
Illegal instruction (core dumped)@\<--program dies
host%
@end(format)

We know what type of problem to look for (a division by zero),
 but we don't know exactly
which statement is causing the problem.

When run on RT PC workstations, the problem shows up differently:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inch)
rthost% @b(a.out)
  Type in a b and c separated by blanks, then hit RETURN
@b(0 5 7)
  The two roots are:   -INF   NAN()@\<- program produces strange 
  Exiting, Bye!@\<- output, but no error message
rthost% 
@end(format)

The RT PC  example doesn't generate any error message, but it produces a
result that wasn't expected.  

@subsection(Where Is the Problem?)
To find out which statement caused the run time error 
we can use a debugger called @i(dbx).  @i(dbx) is a powerful
tool which can be used to find many run time errors.  
There are different debugging strategies to find different
kinds of run time errors.  Two of these strategies are shown
below.

@paragraph(Finding the Statement Where a Program Core Dumps)
To find out which statement caused the core dump in the VAXstation 
example:

@begin(enumerate)
Recompile the program, but use the @b(-g) option.
This tells the
compiler to produce debugging information. You @i(must)
add the -g option.
@begin(format, leftmargin +3)
host%  @b(f77 -g quad.f)
@end(format)

Start up the @p(dbx) debugger program on the @i(binary
file). 
@begin(format, leftmargin +3, size 9)
@tabclear
@tabset( 3.0 inch)
host% @b(dbx a.out)@\<--start dbx on a.out
dbx version 3.24 of 6/14/87 22:31 (paris)
type 'help' for help. @\<--dbx announces itself
reading symbolic information ...@\     ending with the (dbx) prompt
(dbx)@\<--you now type dbx debug commands
@end(format)

Tell @i(dbx) to start running the program, and respond @i(exactly)
as before: @begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inch)
(dbx) @b(run) @\<--run the program
 type in a b and c separated by blanks, then hit return
@b(0 5 7)@\<--reply exactly as before

floating point exception in main at line 23
  23     x1 = ( -(b) - (sqrt(underradical)) ) / ( 2 * a )
(dbx)@\<--aha! the offending line
@end(format)
The error message is more obscure than before, but the line
that causes the problem prints.  By looking at the divisor, we
can deduce that @i(a) must be zero.  Well, yes, of course, that's
what we said.  Clearly, the problem with
@i(quad.f) is that  we need to test for the case where @i(a)
is zero (figure is not a parabola, but a line) and do something
special about it.  We could also tell @i(dbx) to print the value of
variables: @begin(format, leftmargin +3)
(dbx) @b(print a)
0.0
@end(format)

When you have found your error, be sure to leave @i(dbx) with the @i(quit) 
command:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inches)
(dbx) @b(quit)@\<--leave dbx with quit command
@end(format)
@end(enumerate)

@paragraph(Stepping Through a Program)
In the RT PC example, you will need to proceed a little differently,
since you know very little about the error.
The program doesn't stop and there is no message saying what happened
or where it happened.  
To find the problem here, you will want to "slow down" the program's 
execution,
and look at the values of each variable after each statement is executed.
Using this technique to find your runtime errors is like watching a movie
one frame at a time instead of at full speed.  While you don't get to
enjoy the movie as it was intended, you can look at all the details you
would otherwise miss.

The only clues you can work with are the values output in the example:
@i(-INF) and @i(NAN()).  The value @i(-INF) is used to represent an
infinite number; these values are generated to replace values that are
too large (overflow) or too small (underflow) to be stored in the computer.  
Also, @i(INF) 
is the value returned by calculations such as division by zero.  The 
@i(NAN) (which stands for @b(N)ot @b(A) @b(N)umber)
is output as the result of a calculation performed with @i(INF) as one
of its terms.
The @i(INF) and @i(NAN) values indicate errors in the
statements that compute values.  

To find this type of error:
@begin(enumerate)
Compile your program with the @b(-g) option; this option tells @i(f77)
to include debugging information in the binary file @i(a.out) that it
creates:
@begin(format, leftmargin +3)
rthost% @b(f77 -g quad.f)
quad.f:
   MAIN:
rthost%
@end(format)

Create a line-numbered listing of your program:
@begin(format, leftmargin +3)
rthost% @b(cat -n quad.f | lpr)
@end(format)
This line-numbered listing will help you to see which statement @i(dbx) 
is currently looking at, and what has happened up to that point.
You will need this listing as you step through the program.  If you
are using a workstation, you may want to display the line-numbered 
listing in your login window; use the procedure described earlier, 
called "Another Technique," to display the line-numbered program
in your login window.

We're now going to start @i(dbx) and step through the program one statement
at a time, and examine the values in the variables until the @i(INF)
or @i(NAN) show up.  The process is rhythmic--execute a statement,
look at the variables, execute the next statement, look at the
variables, etc.  There is one oddity to what you'll see below.  When
@i(dbx) executes a statement, it doesn't then print out @i(that)
statement; instead it prints out the next statement it would execute.
When @i(dbx) executes 20, it prints statement 21.  Remember that the
action is really one statement back from the one that you see.
@begin(itemize)
Run the debugger on the @i(binary file):
@begin(format, leftmargin +3, size 8)
@tabclear
@tabset(3.0 inches)
rthost% @b(dbx a.out)@\<- start dbx on a.out
dbx version of 1986-03-16 5:24 (garp.mit.edu)
Type 'help' for help.@\<- dbx announces itself
reading symbolic information ...@\   ending with the (dbx) prompt
(dbx)@\<- now type dbx debug commands
@end(format)

After @i(dbx) loads the binary file, it will prompt you with @i((dbx))
and wait for you to type a command.  Find the first @i(executable) statement
in the program; executable statements are statements which @b(do) things.
Comment lines, declaration statements, and blank lines aren't
executable, but statements which 
read and write information, or do computations @i(are) executable
statements.  Since we know that the error happened as a result of some bad 
arithmetic, we should slow down the program execution where the calculations
begin.  The first executable statement which we are interested in is line 
number 22, since this is where the first calculation happens.
Tell @i(dbx) to stop just @i(before)
executing line 22:
@begin(format, leftmargin +3, size 8)
@tabclear
@tabset(3.0 inches)
(dbx) @b(stop at 22)@\<- stop before the first calculation
(1) stop at 22
@end(format)

Now run the program as you did before:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inches)
(dbx) @b(run)@\<- now run the program
@end(format)

When dbx stops and gives you the @i[(dbx)] prompt, you can look at the 
values of the variables with the dbx @i(print) command:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inches)
stopped in MAIN at line 22
   22           underradical = (b**2) - ( 4 * a * c )
(dbx) @b(print a, b, c)
0 5 7
(dbx)
@end(format)

When you are done looking at the variables, you can tell dbx to 
execute this statement and stop before executing the next statement:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inches)
(dbx) @b(step)@\<- execute line 22
@end(format)

Repeat the last two steps until you find where your error is.
@end(itemize)
@end(enumerate)

Here is an example of a @i(dbx) session which uses this strategy:
@begin(format, leftmargin +3, size 9)
@tabclear
@tabset(3.0 inch)
rthost% @b(dbx a.out)
dbx version of 1986-03-16 5:24 (garp.mit.edu).
type 'help' for help.
reading symbolic information ...
(dbx) @b(stop at 22)@\<- tell dbx to stop just before the first computation
(1) stop at 22
(dbx) @b(run)@\<- now run the program
  Type in a b and c separated by blanks, then hit RETURN
@b(0 5 7)@\<- answer just as you did before
stopped in MAIN at line 22@\<- dbx has executed line 18 and stopped
   22   	underradical = (b**2) - (4 * a * c )
(dbx) @b(print a, b, c)@\<- look at the values for a, b, and c 
0 5 7
(dbx) @b(step)@\<- now run line 22 and stop before line 23
stopped in MAIN at line 23
   23   	x1 = ( -(b) - (sqrt(underradical)) ) / ( 2 * a)
(dbx) @b(print underradical)@\<- now that underradical has a value you can
25 @\    examine it
(dbx) @b(step)@\<- execute line 23 now
stopped in MAIN at line 24
   24   	x2 = ( -(b) + (sqrt(underradical)) ) / ( 2 * a)
(dbx) @b(print x1)
-INF@\<- Aha!  Here's one of the errors 
(dbx) @b(print a)
0 @\<-  (2 * a) = 0; this causes a "divide by zero" error
(dbx) @b(quit)@\<- we've found the error, so quit
rthost% 
@end(format)

To fix the error you need to add statements to check @i(a) to see if
its value is zero.  
The modified @i(quad.f) would look like this:
@begin(example, size 8)
C                                           2
C   Program to solve quadratic equation:  ax  + bx + c
C
C               ---------
C          +   / 2
C       -b - \/ b  - 4ac
C   x = -----------------
C              2a
C
C234567**********************************************************************
C Declarations

      real  a, b, c,  x2, underradical

C Ask for initial values from user, then read what he typed

      print *, 'Type in a b and c separated by blanks, then hit RETURN'
      read  *, a, b, c

C Check if a=0  (line, not parabola)  

      if ( a .EQ. 0) then                                           @b(<- here's the fix!)
         print *, 'a is 0, this is a line'
         go to 200
      endif

C Now go ahead and compute values

      underradical = (b**2) - (4 * a * c)
      x1 = ( -(b) - (sqrt(underradical)) )  /  ( 2 * a )
      x2 = ( -(b) + (sqrt(underradical)) )  /  ( 2 * a )

C Print results

      print *, 'The two roots are:', x1, x2
      
C And leave

200   print *, 'Exiting.  Bye.'
      end

@end(example)

There is another run-time bug hiding in this program.  The program
does not check to see if the value under the radical is negative,
leading to an attempt to take the square root of a negative number,
producing an irrational result.  On some computer systems, the
built-in @i(sqrt) function would check for this case and flag
an error.  On the Unix system,  the
@i(sqrt) function just returns 0.  
Without an explicit, programmer-supplied
check, this program will quietly produce incorrect results.

Type @i(man dbx) for more information on the @i(dbx) debugger. 
The Athena document @i(More C) will also be available in the Athena
terminal clusters; this document has an extensive description of
the @i(dbx) debugger.
@section(Linking to Libraries)

You don't have to write Fortran code "from scratch" for everything
you want to do.  Any respectable system comes with an 
assortment of libraries that you can call
from Fortran to do anything from take a
square root to compute an eigenvalue to draw an x-y plot from
an array of data.  There are many such libraries on Athena.
Some come with the Unix system, others Athena  added as extras,
such as the NAG library of mathematical routines and the Penplot
graphics package.
@foot(As of this printing, none of these extra libraries are
available on the RT PC workstations.  Only the libraries supplied
with Unix exist for the RT.  If you will need to use these extra
libraries you should plan on using a VAXstation.)
Most of the "public" libraries are kept
in the directories @i(/lib), @i(/usr/lib), or @i(/usr/athena/lib).
You can construct your own private libraries with the @i(ar)
utility.  Many courses have done this.

Consult your Fortran text for the general rules 
on how to call functions and subroutines within a program.
The important things to get right are the name of the function/subroutine,
and the number and type of its arguments.  @i(f77) and the
run-time system do not check that you have called a function
with the proper number of arguments or that the types
(integer, real, etc.) match.  This frequently causes obscure run-time
bugs.

To use a library, you must link to it at compile time, as follows:
@begin(format, leftmargin +3)
f77  @i(options)  @i(sourcefile.f)  @b(-l)@p(libname)
@end(format)
The @b(-l) option specifies the library to link to.  All -l
options must come at the @i(end) of the compile command, after
all filenames.  There can be @i(no blanks) between the -l
and the library name.  You can specify more than one library; they
will be linked in the order given.

The -l option, by default, searches the @i(/lib, /usr/lib), and
@i(/usr/athena/lib) directories for files of the form:
@b(lib@p(name).a).  For example, -lnag will look in the three library 
directories until it finds a file named @i(libnag.a).

@subsection(Linking to the NAG Library)
To link to the NAG library:
@begin(format, leftmargin +3)
host%  @b(f77  @p(options)  @p(sourcefile.f)  -lnag)
@end(format)

@subsection(Linking to the Penplot Library)
To link to Penplot:
@begin(format, leftmargin +3)
host% @b(f77  @p(options)  @p(sourcefile.f)  -lpenplot)
@end(format)

@subsection(Linking to Private Libraries)
You can link to private libraries, such as those created for a
class, provided that you have read permission on the file.  To
link to a private library, just give the complete filename
of the file that contains the library.  Do not use -l.  For
example:
@begin(format, leftmargin +3)
host% @b(f77  mysource.f  /mit/user/lib/draw.a)
@end(format)
would link @i(mysource.f) to the @i(draw.a) library under the user's library subdirectory.

@subsection(Linking Errors: "Undefined" and "Permission Denied")

@b(-l) is actually an option to a separate linking program, @p(ld),
not to the @i(f77) compiler.  @i(f77) always calls @i(ld) as
its last step (unless you specify -c for "compile only").  When
@i(f77) calls @i(ld), it tells it which libraries to search.
@i(f77) always has @i(ld) search:  @i(/lib/libc.a) (Unix
Programmer's Manual sections 3, 3S, 3N, 3X, and 3C), @i(/usr/lib/libm.a)
(the math library, manual section 3M), @i(/usr/lib/libU77.a, /usr/lib/libF77.a),
and @i(/usr/lib/libI77.a) (the Fortran libraries, manual section 3F).
You should realize that, if you ever use @i(ld) separately,
without @i(f77), @i(ld) will @i(not) look in these files
automatically; many things will become undefined.  If you have
doubts about which libraries are being linked in, use the
@b(-t) (for "trace") option on the compile command.

If @i(ld) finds linking errors ("Undefined:" error messages),
it will still produce a binary file named @i(a.out)
(or whatever you specified),
but it will set its file protection to "no owner execute."  
If you try to run such a file anyway, you will get a "Permission denied."
error message.  Verify that this is the problem with:
@begin(example, size 8)
ls -l a.out
-rw-------  1  you   37888 Sep 1 16:15 a.out*
   |
   | No "x" for owner execute
@end(example) 


@section(Simple File I/O)

By default, Fortran reads its input from the keyboard, and writes its output
and errors to the  screen.  More precisely, Unit 0 (errors) is
assigned to the Unix data stream @i(stderr), Unit 5 (input) is assigned to
Unix data stream @i(stdin), and Unix 6 (output) is assigned to the Unix 
stream @i(stdout).  This means that you can easily redirect your input
and output away from the keyboard and screen and have it come to and
from files using the Unix I/O redirection mechanisms.

If a compiled program @i(myfile) contained the two statements:
@begin[example,size 8]
read  *,a
write *,a
@end(example)
and was subsequently executed as follows:
@begin(example, size 8)
host% myprogram
@end(example)
it would read its input data from the keyboard and write it to the
screen.

If it were invoked as follows:
@begin(example, size 8)
host%  myprogram  <testdata   >results
@end(example)
it would read from the file @i(testdata) in the current directory
and write to a file @i(results), also in the current directory.  Much
more elaborate I/O operations to files are possible.  See the
document "Introduction to the f77 I/O Library," part of the Athena
@i(Fortran) manual for details.


@section(For More Information)

If you plan to do much Fortran programming, you will need to buy
a good book on Fortran 77, both to teach yourself the language,
and to use as a reference manual for syntax questions.  There are
dozens of Fortran 77 books.  We recommend @i(Fortran 77 for Humans),
Second Edition, by Page, Didday and Alpert, West Publishing Co.,
ISBN 0-314-69672-5.@foot{Be careful not to get @i(Fortran for Humans)
by the same author; it is for a very different, outdated version
of Fortran}
Note in particular the "Quick Reference Index" on its last page.

The IS Publications Office in 11-209 (M-F, 10 am to 4 pm) sells
this book.  It is used as a text for 2.10, and so the Coop usually
has it as well.  Reference copies are available in each cluster
in the manual rack.

To learn more about the @i(f77) compiler, there is:  
@begin(itemize)
Type:  @i(man f77) --  this will show you the other options on the
@i(f77) command.

The Athena @i(Fortran) manual contains two documents:  "A Portable
Fortran 77 Compiler" and "An Introduction to the f77 I/O Library."
You should get these if you will be doing serious Fortran work.
They tell you things such as this compiler's extensions to the Fortran 77
standard, and details of I/O to files.  Reference
copies are in each terminal cluster manual rack.  You can buy
the manual at the IS Publications Office.
@end(itemize)

Very specific information on libraries is found in the Unix Programmer's
Manual, section 3.  This is sold as @i(The Unix Programmer's Reference Manual)
through IS Publications.  Reference copies are in the racks.  The easiest
way, though, is to examine the material online.  Type:  @i(man 3 intro)
for the introduction to libraries.  @i(man ar) describes sketchily
how to make libraries.  @i(man nm) describes how to examine their
contents.  Penplot and NAG documentation is available in the cluster
reference racks.  The NAG manual is a large green, 6-volume set.
The small Penplot manual is also sold at IS Publications.

The @i(dbx) debugger is described on its man page; type @i(man dbx).
It is also described in the Athena @i(More C) document, which will be 
available in the cluster reference racks and at the IS Publications
Office.

@newpage
@section(Appendix A: Compile Errors)
 
@begin(format, flushright, font bodyfont)
@i(These appendices showing f77 
error messages were originally compiled
for subject 2.10 by John Kyratzoglou and
Dan Ottenheimer)

@end(format)


@BEGIN(DESCRIPTION) 
ASSIGNMENT TO AN UNDIMENSIONED ARRAY
@\An assumed array name was used, where the array name was not declared
in a declaration statement.

BAD ARGUMENT TYPE TO INTRINSIC FUNCTION
@\A function reference was made, using an intrinsic function name,
but the argument list does not agree in order, number or type with the 
intrinsic function requirements.

BAD MAGIC NUMBER
@\For a FORTRAN file the extension must be @B<.f>. For a C file the 
extension must be @B<.c>.

DECLARATION ERROR DECLARATION AMONG EXECUTABLES
@\The order of the statements was not as specified in 
the FORTRAN Language Reference Manual. The statement found out of order is 
ignored.
@begin(example) 
        Example :
                 N = 10
                 REAL X(N)
@end(example)
Here an executable statement precedes  a declaration statement.

DECLARATION ERROR DECLARATION: INCOMPATIBLE TYPE DECLARATION
@\The same variable appears in more than one but different data type 
declaration statements. As an example,
@begin(example)
       REAL X(5)
       INTEGER X(5)
@end(example)

DECLARATION ERROR FOR AN ENTITY, USED AS VARIABLE
@\An entity has been used incorrectly; for example, the name of a 
subprogram was used where an arithmetic expression is required.

DECLARATION ERROR FOR ENTITY: INCONSISTENT EQUIVALENCE
    @\EQUIVALENCE statements specify inconsistent relationships between
variables or array elements. As an example,
@example{
EQUIVALENCE (A(1), A(2))}

DECLARATION ERROR LENGTH MUST BE A POSITIVE INTEGER CONSTANT
@\An unacceptable length has been specified in a data type declaration.
This statement is not allowed.
@begin(example)
  Examples:
           INTEGER NUM*3
           CHARACTER*  NAME
@end(example)

DECLARATION ERROR FOR VARIABLE, IMPROPERLY DIMENSIONED ARRAY
@\A reference was made to an adjustable array in a context where such
a reference is not allowed. Example:
@begin(example)
         parameter(nc=20, nchar=3)
         real x(n)
@end(example)
The variable n specified  giving the array size must be either 
initialized in the parameter statement or must be subprogram dummy 
argument or appear in common.

DO LOOP OR BLOCK IF NOT CLOSED
@\The terminal statement of a DO loop or the END IF statement of an 
IF block was not found.

EXECUTION ERROR ENDIF OUT OF PLACE
@\Invalid control structure using ELSEIF, ELSE, or ENDIF. The order 
of the above statements is incorrect.

EXECUTION ERROR LABEL ALREADY DEFINED
@\The same label appears on more than one statement.

EXECUTION ERROR, UNCLASSIFIABLE STATEMENT
@\Compiler cannot figure out what kind of statement it is.  Sometimes
caused by misspelled keywords or unbalanced quotes that create nonsense
statement fragments.

EXECUTION ERROR, UNLABELED FORMAT STATEMENT
@\A required label in a format statement was ommitted.

FLOATING EXCEPTION DURING CONSTANT EVALUATION
@\The specified value of a constant is too large or too small to 
be represented.

IMPOSSIBLE CONVERSION @begin(multiple)
@\An expression that must be arithmetic(INTEGER, REAL, LOGICAL) was
of type CHARACTER.

An expression that must be of type CHARACTER was another data type.

A variable is not declared properly.
@end(multiple)

IMPOSSIBLE STORAGE CLASS 8 IN ROUTINE
@\Often caused by attempt
to use a non-array variable as an array.  Often paired with
"DECLARATION ERROR" message.

INVALID CONTROL ACCESS FOR STATEMENT
@\The ACCESS= keyword specified in an I/O statement was the one assumed
when the file was created.

INVALID CONTROL END FOR STATEMENT 
@\The END=keyword was used illegally in a WRITE or direct access READ
statement.

LABEL ALREADY THAT OF A FORMAT
@\Labels of executable statements have been confused with labels of
FORMAT statements or with labels of non executable statements.

LOGICAL DATUM ASSIGNED TO A REAL VARIABLE
@\In a data statement a logical constant was assigned to a real variable.
Example:
@example( data bzro /.true./)

LD:@i(filename): CANNOT OPEN
@\File type of @i(filename) was not specified during the creation 
of a FORTRAN or C file. As a result during the execution of the shell
command 
@begin(example)
      % f77 for.
    or
      % f77 for
@end(example)
the file could not be opened and compiled.

LOCAL VARIABLE "X" NEVER USED
@\A particular variable was referenced but never used in the program.

MISSING END STATEMENT
@\An END statement was missing at the end of the last input file.

MISSING STATEMENT NUMBER
      @\Reference has been made to statement label that is not defined in the
program unit.

MORE DATA VALUES THAN DATA ITEMS
@\The number of variables or array elements to be initialized must
match the number of constants specified in data initialization.

NAME " name " TRUNCATED TO 16
@\" name " was longer than 16 characters and has been truncated.

NONDIGIT IN STATEMENT NUMBER FIELD
@\An improperly formed statement label(namely one containing letters)
has been detected in columns 1 to 5 of an initial line. The statement label
was ignored. 
 
NONLOGICAL EXPRESSION IN IF STATEMENT
@\An expression that must be of type LOGICAL  was another data type.

NONLOGICAL OPERANT OF LOGICAL OPERATOR
@\An invalid operation was specified as .AND. of two real variables.

NUMERIC DATUM ASSIGNED TO A CHARACTER VARIABLE
@\Character data with a length greater than one was initialize with 
a numeric value in a DATA statement. As an example:
@example{
character*10 name
data name /14/}

REPEATED KEYWORD
@\Each keyword subparameter in an I/O statement or auxiliary I/O
statement can be specified only once.

SUBSCRIPTS ON A SIMPLE VARIABLE
@\A variable that is not defined as an array cannot appear with subscripts.

SYNTAX ERROR
@\This is the catch-all error message for syntax problems.
Some frequent causes:
@begin(itemize)
@\An expression or a term of an expression has been ommitted ( missing 
variable or constant).
@begin(example, size 9)
 Example : RESULT =    * TIME
           SUMMATION =      
	   WRITE(6, FMT='(1X, F3.1)') SUM
@end(example)

Superfluous text was found at the end of a syntactically correct
statement. Check for typing or syntax errors (extra characters following 
a valid statement).
@example( Example :  ICOUNT = ICOUNT+1, )

A required variable or subprogram name was not found.

Two terms of an expression are not sepatated by an operator or a
punctuation mark(such as comma) has been omitted.

A floating-point constant was specified in E notation but the 
exponent was omitted.

A required constant was not found.

A character constant must be enclosed in parenthesis.

An invalid operation was attempted in an implied-DO list in a 
DATA statement, for instance a function reference in the subscript or
substring expression of an array or character substring reference. Example:
@begin(example, size 9)
DATA (A(SIN(REAL(I))), I=1, 10 )   /100.0/
@end(example)

Extra comma in format list.
@end(itemize)

TERMINATION CODE 139
@\The upper bound of a dimension declarator must be equal to or
greater than the lower bound.

THERE IS A BRANCH TO STATEMENT LABEL FROM OUTSIDE BLOCK
@\DO or IF statement incorrectly nested.

UNBALANCED PARENTHESIS, STATEMENT SKIPPED
@\Two terms of an expression are not
separated by an operator or a punctuation mark (such as comma,parenthesis)
has been omitted.

UNBALANCED QUOTES; CLOSING QUOTE SUPPLIED, (SYNTAX ERROR)
@\A missing quote was detected  and supplied by the system.

UNDEFINED:
@\Followed by a list of routine names.  The linker @i(ld) cannot
find the routines in the libraries searched.  To check which
libraries were searched, recompile with -t option.

UNDEFINED ENTITY :
@\A control parameter expression in an implied-DO list in a DATA
statement contains a name which is not the name of a control variable 
of an implied-DO list which has the name of its scope. Example:
@EXAMPLE{ DATA (A(J), J=1,10),(B(I), I=J,K) /100./ }

WRITE SFE:[100] ERROR IN FORMAT
ILLEGAL INSTRUCTION
@\@BEGIN(itemize, spread 0)
Extra comma in format list

Extra number in format list

An invalid character or a syntax error was detected in a FORMAT 
statement.
@end(itemize)

WRONG NUMBER OF SUBSCRIPTS
@\More or fewer dimensions are referenced than were declared for the
array.

ZERO STEP IN IMPLIED DO LOOP
    @\An invalid control parameter was detected in an implied-DO list
in a data statement; for instance an increment of zero.


@end(description)


@section(Appendix B:  Run-Time Errors)

@begin(description)
ASSIGNMENT TO AN UNDIMENSIONED ARRAY
@\An assumed array name was used, where the array name was not declared.

ARITHMETIC EXCEPTION: FLOATING DIVIDE BY ZERO
@\During a floating point arithmetic operation, an attempt was made to
divide by zero.

ARITHMETIC EXCEPTION :FLOATING POINT OVERFLOW
@\During an arithmetic operation, a floating point value exceeded
the largest representable value for that data type.

BUS ERROR
@\The number of arguments in the dummy argument list is greater than
the number of arguments in the actual argument list in a main/subprogram
to subprogram interface (access violation, RM=01).

READ UNEXPECTED CHARACTER
@\During a formatted operation, an invalid character was detected
in an input field, or the input value overflowed the range representable
in the input variable (Input conversion error).

* * * (ASTERISKS)
@\During a formatted output operation the value of a particular number 
could not be output in the specified field length without loss of
significant digits. The field is filled with asterisks (Output conversion
error).

DOFIO :[-1] END OF FILE DURING READ
@\An end-of-file condition was encountered during execution of
a READ statement that did not contain an END, ERR or IOSTAT specification.

IERR = -1
@\Attempt to access a nonexistent record.

IERR = 104
@\Mixed access modes. An attempt was made to use formatted and 
unformatted operations on the same unit.

IERR = 103
@\access='sequential' was performed on a direct access file.

ILLEGAL UNIT NUMBER
@\A logical unit number greater than 99 or less than zero was used
in an I/O statement.

PERMISSION DENIED.
@\There were errors during linking when you compiled the program.
("Undefined:")  The linker has set the file's protection to
"no owner execute."

@end(description)

@section(Appendix C: Errors Undetected by f77 )

@begin(enumerate)

The control variable of a DO loop has been altered within the range 
of the DO statement. Assignment to DO variable within loop. Example:
@begin(example) 
       do 14 i=1,20
         i = 20       	
         x(i) = 0
    14 continue
@end(example)

Extra comma in format list.
Example :
@begin(example)
       Format(1x, a, f3.1,)
@end(example)

Missing separator between format items. A required separator character
has been omitted between fields in a FORMAT statement. Example:
@begin(example)
       Format(1x, a  f3.1)
@end(example)

A variable appears in more than one data type declaration statement. Or
a name appears in two or more inconsistent declarations statements
(Multiple declaration of name).
@begin(example)
         real x(5), x(5)
   or
         real x(5) , ....
         real x(5) , ....
@end(example)

Missing number in format list
@begin(example)
Example :    FORMAT(1x, a, f6. )
@end(example)
The system assumes that the number of characters to the right of decimal
point is one and there is an accuracy error involved.

Using an array within a program without declaring it with a DIMENSION 
statement.
@Begin(Example)
Example:
  c
       do 14 j=1,20
        x(j) = 10.5
        write(6, fmt=*) x(j)
  14  continue
  c
      stop
      end
@end(example)
          
@end(enumerate) 
