Conventions for labelled DO statements (F77)

Given a loop such as

      DO 3 J = 1, L
         DO 3 I = 1, N
            X(I,J) = 0.0D0
   3  CONTINUE

I get a warning about a F2018 deleted feature:

...src/ptls.f:59:72:

   59 |          DO 3 I = 1, N
      |                                                                        1
Warning: Fortran 2018 deleted feature: Shared DO termination label 3 at (1)

To get rid of the error I would like to introduce a separate termination label. Naively, I would increment the outer loop label to 4, however the labels 4 to 15 are already used in the rest of the code (not shown).

What would be a typical Fortran 77 programmer convention for picking labels?

My current plan is to multiply all existing labels by 10, and then rewrite the loop as follows:

      DO 31 J = 1, L
         DO 30 I = 1, N
            X(I,J) = 0.0D0
  30     CONTINUE
  31  CONTINUE

Please note I have no interest in switching to free-form at this stage; I’m just looking for the minimal changes needed to compile this fixed-form program without warnings.

1 Like
  1. Is -std=legacy a compiler option you can use? That might suppress the warning while also supporting certain earlier semantics and syntax if this fixed-format source code employs those features. That way, you may able to use the code with no change.

  2. You will note though this is not a fixed vs free-form source aspect: rather, the matter you have at hand pertains to the deletion of the Nonblock DO construct from the standard beginning Fortran 2018. Starting Fortran 90 revision when free-form source was added, a Nonblock DO construct could be used in free-form source as well. And because fixed-form source is marked obsolescent instead of being deleted (which it will never be, if one were to venture a guess), fixed-form source remains effectively a “first-class” feature with all the standard semantics having to work in that source form as well. Thus you can employ all the modern Fortran standard features in fixed-form source code, if you so choose.

You are probably putting way too much effort toward maintaining f77 compatibility. Just change the code to

      DO J = 1, L
         DO I = 1, N
            X(I,J) = 0.0D0
         ENDDO
      ENDDO

or even

X(1:N,1:L) = 0.0D0

and move on to worry about other things.

I was aiming primarily for consistent appearance with the rest of the code. A second reason was the possibility to use f2c (g77 -ff77) but I checked and f2c accepts also some Fortran 8X syntax including the “modern” do loop syntax.

The code is not in such bad shape. Besides a few unused variables (there might be bugs…), missing declarations, and the shared DO termination, there are no other issues.

Indeed. I will follow @kargl’s and your suggestion.

As a matter of curiosity, I’m still interested in the practical “rules” used to increment labels without getting a headache during editing. Was it just a matter of incrementing/decrementing 10’s? Did historical editors or key-punches have any way of tracking such labels or was it all tracked manually?

1 Like

I think it was mostly all done manually. However, there were tools in the 1970s at least that would renumber statement labels in the order that they appeared in the subroutine. The user had some control over the range and spacing of the output labels.

There were also tools used by some commercial vendors that would uglify code. Namely, they would change all of the variable names to mixtures of “1” “I”, “O” and “0” (that’s one, capital I, capital O, and zero) as a way of obscuring the algorithm and the code. It would compile correctly afterwards, but it was almost impossible to maintain or modify in that form.

2 Likes

I find numeric labels more disturbing than most any pre-f90 features myself with a few minor exceptions,
but there used to be rule books. One such suggested that any outer do-loop be a multiple of 10,
that formats be 101, 202, 303, 404 … unless there were a large number in which case they could be 101, 102, 103, …; that nested do-loops end with a 5; and that you never used a goto to a label that was a multiple of 5 except from inside the do loops. That lines used as targets of a goto (assumed not to be the foot of a DO, which would be repeated digits (with a minimum of two) such as 11, 22, 33, … and that famiies of related targets from something like a computed goto be prefixed with multiples of ten but be four or more digits, like 1001, 1002, 1003, 1003, … There were others but I have seen that one used in a number of codes I still run across. And 99999 or 9999 was recommended as a target at the end of the procedure and that a goto 99999 was preferred over multiple returns with a few other dusty corner rules. It was suggested that values increase from the top to the bottom of the procedure; and renumbering utilities were relatively common that often let you resequence the numbers as code was rearranged. It was suggested you increment by several steps to leave room for still following the suggestions for things other than formats (which can be arbitrarily placed so they are easy to keep sequential, say at the end of a procedure (I usually prefer the formats being at the point of use if only used once, so I did not follow that one very often, personally). So when first writing the code you might increment do loop numbers by 20 or 50 so it would be easy to backfill. Several of the renumbering programs still exist, I think some are listed on the Fortran Wiki.

There certainly were no hard and fast rules, however. Looking through code on NETLIB proves that pretty quickly. But you would be moving in the right direction to use any syntax that lets you remove numeric labels where not absolutely required IMO (such as the ENDDO recommended above).

As in the past you can make up your own rules for numeric labels though. But since you mentioned it, there were several camps with suggested rules, and (at least as I recollect it) that was a description of one of them.

The general idea was to use patterns that let you identify the use of the label (foot of loop, target of goto, format, value used by ASSIGN, value used by a call to a procedure with multiple returns, …) just by the value alone; so it was not the exact numbers used, it was establishing such a pattern that was suggested.

Once CONTINUE was introduced, many guides strongly suggested all numeric lines (except for FORMAT statements of course) be CONTINUE statements to reduce the confusion labeled executable lines caused, especially when used as the foot of a do loop.

2 Likes