{"id":11217,"date":"2025-07-17T02:00:00","date_gmt":"2025-07-17T06:00:00","guid":{"rendered":"https:\/\/www.both.org\/?p=11217"},"modified":"2025-07-15T16:26:56","modified_gmt":"2025-07-15T20:26:56","slug":"3-ways-to-write-bugs-with-fortran-77","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=11217","title":{"rendered":"3 ways to write bugs with FORTRAN 77"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"11217\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p>I learned FORTRAN 77 programming when I was an undergraduate physics student in the early 1990s. While the Fortran 90 version of the language had been defined since 1990, and accepted by ANSI shortly after, my university didn&#8217;t have a Fortran 90 compiler on our VAX systems. And because FORTRAN 77 was long known as the <em>standard FORTRAN<\/em>, I never bothered to learn the newer variations.<\/p>\n\n\n\n<p>I used FORTRAN 77 throughout my undergraduate career to analyze lab data. I also programmed in FORTRAN 77 during a summer internship at a research laboratory; when the other researchers realized I &#8220;knew FORTRAN,&#8221; they asked me to update an older program that was originally written in FORTRAN IV, then updated to FORTRAN 66, and later to FORTRAN 77. This really gave me a &#8220;deep dive&#8221; into some weird corners of FORTRAN.<\/p>\n\n\n\n<p>FORTRAN 77 introduced the familiar <code>IF<\/code> and <code>END IF<\/code> blocks, with optional <code>ELSE IF<\/code> and <code>ELSE<\/code> statements, but earlier editions supported some strange <code>IF<\/code> variations to create conditional branches. In fact, three structures from the original FORTRAN (version 1 from the mid 1950s) were interesting solutions, but can cause endless headaches if used in modern times.<\/p>\n\n\n\n<p>These structures will be very unfamiliar for new programmers, so I wanted to share this short list of 3 ways you can use these features to add interesting bugs to your FORTRAN programs:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"arithmetic-if\">1. Arithmetic IF<\/h2>\n\n\n\n<p>Classic FORTRAN has a three-way <code>IF<\/code> statement that can jump to different statement labels (labels are similar to <em>line numbers<\/em>, but not really) depending on the value of a variable. It looks like a normal <code>IF<\/code> statement, but you give an expression or value inside parentheses, then a list of three statement labels.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      IF (N) 20, 90, 30<\/code><\/pre>\n\n\n\n<p>The <code>IF<\/code> jumps to the first label if the value is less than zero, to the second label if the value is equal to zero, and the third label if greater than zero. Since that covers all possible values, the program should never just <em>continue<\/em> to the next statement; it should always jump to a new statement.<\/p>\n\n\n\n<p>Here&#8217;s a sample program that shows the Arithmetic <code>IF<\/code> in action. This reads an integer from the user, and prints if it is less than zero, equal to zero, or greater than zero. Enter <strong>0<\/strong> to quit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      PROGRAM ARITHIF\n      INTEGER N\n10    PRINT *, 'ENTER N: (0=STOP)'\n      READ *, N\n      IF (N) 20, 90, 30\n      PRINT *, 'ERROR?'\n      GOTO 10\n20    PRINT *, '.LT.0'\n      GOTO 10\n30    PRINT *, '.GT.0'\n      GOTO 10\n90    PRINT *, '.EQ.0'\n      END<\/code><\/pre>\n\n\n\n<p>Note that the two lines immediately after the Arithmetic <code>IF<\/code> should never be executed; that&#8217;s why I printed an error message, then looped back to the start:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      PRINT *, 'ERROR?'\n      GOTO 10<\/code><\/pre>\n\n\n\n<p>Compile and run this program, then type in a few values to experiment with the Arithmetic <code>IF<\/code>. I&#8217;m compiling with GNU Fortran on Linux; if you don&#8217;t have the <code>gfortran<\/code> program, you can install it as the <code>gcc-gfortran<\/code> package. The <code>-Wall<\/code> option prints any warnings, and <code>-std=legacy<\/code> tells the compiler to assume <em>legacy<\/em> code syntax (such as FORTRAN 77) when it compiles the program:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ gfortran -Wall -std=legacy -o aif aif.f\n\n$ .\/aif\n ENTER N: (0=STOP)\n2\n .GT.0\n ENTER N: (0=STOP)\n1\n .GT.0\n ENTER N: (0=STOP)\n-2\n .LT.0\n ENTER N: (0=STOP)\n-1\n .LT.0\n ENTER N: (0=STOP)\n0\n .EQ.0<\/code><\/pre>\n\n\n\n<p>You can see that for 1 or 2, the program prints <code>.GT.0<\/code> which is &#8220;FORTRAN-speak&#8221; for <em>greater than zero<\/em>. For -1 or -2, the program prints <code>.LT.0<\/code>, and for zero is prints <code>.EQ.0<\/code> then quits.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"computed-goto\">2. Computed GOTO<\/h2>\n\n\n\n<p>The Computed <code>GOTO<\/code> is a strange beast that still gives me nightmares. It uses a list of statement labels in parentheses, plus a value or expression. If the value is 1, the <code>GOTO<\/code> jumps to the first label; if 2, it jumps to the second label; if 3, the third label; and so on.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      GOTO (10, 20, 30) N<\/code><\/pre>\n\n\n\n<p>If the value is zero or less, or if the value is greater than the <em>count of labels<\/em>, then control passes to the next statement in the program. If the value is well controlled and you know it will <em>always be in a specific range<\/em>, then this is a neat solution. But beware any programmer that does not put a &#8220;catch-all&#8221; statement after the Computed <code>GOTO<\/code> to trap any errant values.<\/p>\n\n\n\n<p>Here&#8217;s a sample program that demonstrates how to use the Computed <code>GOTO<\/code>. This reads an integer from the user, then prints <code>ONE<\/code> if the value is 1, <code>TWO<\/code> if the value is 2, and <code>THREE<\/code> if it&#8217;s 3. For other values, the program prints a message and loops back to the start; enter zero to quit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      PROGRAM COMPGOTO\n      INTEGER N\n1     PRINT *, 'ENTER N: (0=STOP)'\n      READ *, N\n      GOTO (10, 20, 30) N\n      IF (N.LT.1) PRINT *, '.LT.1'\n      IF (N.GT.3) PRINT *, '.GT.3'\n      IF (N.EQ.0) GOTO 90\n      GOTO 1\n10    PRINT *, 'ONE'\n      GOTO 1\n20    PRINT *, 'TWO'\n      GOTO 1\n30    PRINT *, 'THREE'\n      GOTO 1\n90    END<\/code><\/pre>\n\n\n\n<p>If you compile and run the program, you can test it with a few values to see how the Computed <code>GOTO<\/code> jumps to each statement:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ gfortran -Wall -std=legacy -o cgoto cgoto.f\n\n$ .\/cgoto\n ENTER N: (0=STOP)\n1\n ONE\n ENTER N: (0=STOP)\n2\n TWO\n ENTER N: (0=STOP)\n3\n THREE\n ENTER N: (0=STOP)\n4\n .GT.3\n ENTER N: (0=STOP)\n-2\n .LT.1\n ENTER N: (0=STOP)\n-1\n .LT.1\n ENTER N: (0=STOP)\n0\n .LT.1<\/code><\/pre>\n\n\n\n<p>When you enter zero, that&#8217;s still <em>less than 1<\/em>, so the program prints <code>.LT.1<\/code> before it exits.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"assigned-goto\">3. Assigned GOTO<\/h2>\n\n\n\n<p>The Assigned <code>GOTO<\/code> statement is actually a two-part solution: first you use the <code>ASSIGN<\/code> statement to save a statement label in a variable, then use <code>GOTO<\/code> with the variable to jump to it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>10    ASSIGN 10 TO L<\/code><\/pre>\n\n\n\n<p>\u2026and\u2026<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      GOTO L<\/code><\/pre>\n\n\n\n<p>This can be an interesting way to create a <em>callback<\/em> so you can jump back to some previous instruction, such as before the <code>SUBROUTINE<\/code> was added with FORTRAN II in 1958. But I never found a good reason to use this in a FORTRAN 77 program.<\/p>\n\n\n\n<p>Here&#8217;s an example of an Assigned <code>GOTO<\/code> to see how to use it. This program reads an integer from the user, then prints <code>ONE<\/code> if the value is 1, or <code>TWO<\/code> if the value is 2, or <code>THREE<\/code> if 3. It prints nothing for other values, and quits when the user enters zero:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      PROGRAM AGOTO\n      INTEGER N,L\n10    ASSIGN 10 TO L\n      PRINT *, 'ENTER N: (0=STOP)'\n      READ *, N\n      IF (N.EQ.0) ASSIGN 90 TO L\n      IF (N.EQ.1) ASSIGN 1 TO L\n      IF (N.EQ.2) ASSIGN 2 TO L\n      IF (N.EQ.3) ASSIGN 3 TO L\n      GOTO L\n1     PRINT *, 'ONE'\n      GOTO 10\n2     PRINT *, 'TWO'\n      GOTO 10\n3     PRINT *, 'THREE'\n      GOTO 10\n90    END<\/code><\/pre>\n\n\n\n<p>Notice that statement label 10 has the initial <code>ASSIGN<\/code> statement, which sets the label 10 to the <code>L<\/code> variable. Later, the program can assign another label to the variable, which means we can use a simple <code>GOTO L<\/code> statement to jump to whatever label is stored in the <code>L<\/code> variable at the time.<\/p>\n\n\n\n<p>You can see the Assigned <code>GOTO<\/code> in action if you compile the program and test it with a few values. While I usually use the <code>-Wall<\/code> option to print all warnings, I skipped that option here because otherwise the compiler complains that my statement labels are never used; the GNU Fortran compiler doesn&#8217;t track the labels with the different values in the <code>ASSIGN<\/code> and Assigned <code>GOTO<\/code> statements:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ gfortran -std=legacy -o agoto agoto.f\n\n$ .\/agoto\n ENTER N: (0=STOP)\n1\n ONE\n ENTER N: (0=STOP)\n2\n TWO\n ENTER N: (0=STOP)\n3\n THREE\n ENTER N: (0=STOP)\n4\n ENTER N: (0=STOP)\n-1\n ENTER N: (0=STOP)\n0<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"test-them-with-countdown\">Test them with Countdown<\/h2>\n\n\n\n<p>It might be helpful to compare these methods by writing several programs that <em>do the same thing<\/em> but in different ways. This program is just a &#8220;Countdown&#8221; program; it counts from 10 to 1, and prints each number. The simplest example of this program uses the <code>DO<\/code> loop, introduced to the language in FORTRAN 66. The basic concept of <code>DO<\/code> is the same as a <code>for<\/code> loop in other programming languages; you specify the start, stop, and increment values, and the program iterates a variable&#8217;s value through the loop:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      PROGRAM COUNT\n      INTEGER I\n      DO 10 I= 10, 1, -1\n10    PRINT *, I\n      END<\/code><\/pre>\n\n\n\n<p>If you compile and run the program, you will get a list of numbers counting down from 10 to 1:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ gfortran -Wall -std=legacy -o count count.f\n\n$ .\/count\n          10\n           9\n           8\n           7\n           6\n           5\n           4\n           3\n           2\n           1<\/code><\/pre>\n\n\n\n<p>Now let&#8217;s make the program a little more complicated by using the Computed <code>GOTO<\/code> instead of the <code>DO<\/code> loop. This uses a trivial example of the Computed <code>GOTO<\/code> with just one statement label, so the <code>GOTO<\/code> will only jump to statement 20 (the <code>END<\/code> statement) when <code>N<\/code> has reached the value 1. Otherwise, control passes to the next statement, which decrements the <code>N<\/code> variable and restarts the loop:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      PROGRAM COUNT\n      INTEGER N\n      N = 10\n10    PRINT *, N\n      GOTO (20) N\n      N = N - 1\n      GOTO 10\n20    END<\/code><\/pre>\n\n\n\n<p>A slightly more unnecessarily complex version of the program uses the Arithmetic <code>IF<\/code>. This restructures the program a little bit, by initializing the <code>N<\/code> variable to 10, then entering a kind of &#8220;manual loop.&#8221; The Arithmetic <code>IF<\/code> jumps to label 10 (the start of the loop) as long as the <code>N<\/code> counter variable is greater than zero. When the count reaches zero, the Arithmetic <code>IF<\/code> jumps to line 30 (the <code>END<\/code> statement). This program should never have <code>N<\/code> less than zero, so I&#8217;ve added an error statement as a fallback:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      PROGRAM COUNT\n      INTEGER N\n      N = 10\n10    PRINT *, N\n      N = N - 1\n      IF (N) 20, 30, 10\n20    PRINT *, 'LESS THAN ZERO .. SHOULD NOT GET HERE'\n30    END<\/code><\/pre>\n\n\n\n<p>Walk through the program yourself to see what it does: On the first pass, <code>N<\/code> starts at 10, the program prints it, and then decrements the <code>N<\/code> variable. The new value (9) is greater than zero, so the program starts the loop over again. On the final pass when <code>N<\/code> is 1, the program prints it, then decrements the variable to zero. Since <code>N<\/code> is now zero, the Arithmetic <code>IF<\/code> jumps to line 30, which ends the program.<\/p>\n\n\n\n<p>One more way to write this in the old-style syntax is with the Assigned <code>GOTO<\/code>. This uses a separate variable called <code>L<\/code> to store a line label. Before starting the loop, the program assigns label 10 to the <code>L<\/code> variable; this allows the program to simply use <code>GOTO L<\/code> to jump back to 10 by default. In the last pass of the loop when <code>N<\/code> is 1, the program assigns label 20 (the <code>END<\/code> statement) to the <code>L<\/code> variable, so the program can exit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      PROGRAM COUNT\n      INTEGER N, L\n      ASSIGN 10 TO L\n      N = 10\n10    PRINT *, N\n      IF (N.EQ.1) ASSIGN 20 TO L\n      N = N - 1\n      GOTO L\n20    END<\/code><\/pre>\n\n\n\n<p>Each of these variations of the program do the same thing: count down from 10 to 1, and print each value. Writing the same program in four different ways helps us to compare <em>what the program is doing<\/em> so we can see Arithmetic <code>IF<\/code>, Assigned <code>GOTO<\/code>, and Computed <code>GOTO<\/code> in action.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Explore old-style FORTRAN programming with Arithmetic IF, Computed GOTO, and Assigned GOTO.<\/p>\n","protected":false},"author":33,"featured_media":5230,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[150],"tags":[522,152],"class_list":["post-11217","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming","tag-fortran77","tag-programming"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/33"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11217"}],"version-history":[{"count":1,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11217\/revisions"}],"predecessor-version":[{"id":11218,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11217\/revisions\/11218"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/5230"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}