Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!dino!ux1.cso.uiuc.edu!ux1.cso.uiuc.edu!uxe.cso.uiuc.edu!hirchert From: hirchert@uxe.cso.uiuc.edu Newsgroups: comp.lang.fortran Subject: Re: EQUIVALENCE, COMPUTED GO TO in FORT Message-ID: <50500171@uxe.cso.uiuc.edu> Date: 12 Dec 89 01:31:51 GMT References: <143@suntc.UUCP> Lines: 102 Nf-ID: #R:suntc.UUCP:143:uxe.cso.uiuc.edu:50500171:000:5512 Nf-From: uxe.cso.uiuc.edu!hirchert Dec 11 12:00:00 1989 I'd like to offer a few more points about the "obsolescent features list". o If a series of block IFs were the only possible replacements for assigned GO TO and alternate RETURN, I doubt whether it would have been possible to muster the votes in X3J3 to put them on the obsolescent features list. In both cases, computed GO TO can be used to provide a replacement whose is comparable to that of the original feature. o PAUSE is a bit of a special case. In some systems, it is quite true that one cannot reproduce its functionality with input/output statements. (E.g., on one multiuser system I have used, it holds up the entire system until the system operator responds!) However, none of these extended functionalities are portable. The committee concluded that it was better to use the input/output statements to get the portable functionality and access the special functionalities by calling procedures (written in C or Pascal or Ada or assembly language or whatever is necessary to implement that special functionality on the given machine). o It has been suggested that DO loops with integer indices cannot exactly replace the behavior of loops with real or double precision indices. In fact they can. For example the loop DO 10 X=0.0,1.0,0.1 ... 10 could be exactly replaced by em1=0.0 em3=0.1 iters=(1.0-em1+em3)/em3 X=em1 DO 10a it=1,iters ... 10 10a X=X+em3 [The variable em1 was not really needed in this case; X could have been defined earlier and used in its place. However, in the general case, the expressions controlling the iteration might involve the old value of X, so it might not be acceptable to define X earlier. Similarly, in many cases, it may be possible to simply move the label 10 down to the incrementing of X, but having two distinct labels will be necessary if the loop contains any branches to 10.] The above is simply an encoding of the description of the DO loop found in section 11 of FORTRAN 77. The only case where it might not work would be if the processor handles loops whose number of iterations is greater than the maximum value representable by an integer. The above characterization of this loop also illustrates what is wrong with using real variables as DO loop indices. The expression for the number of iterations can easily give 10 or 11, depending on which way the binary representation of 0.1 is rounded. Even worse, there is an accumulation of error in the incrementation of X, so the successive values of X can be quite different from what is expected. The loop could execute only 10 times with the final iteration being for a value less than 0.9 or the loop could execute 11 times with the final iteration being for a value greater than 1.0. There can be more extreme problems: For example on an IBM mainframe, a loop such as DO 20 Y=1000000.,1000001.,0.01 should execute approximately 100 times with Y equal to 1000000. on every iteration because the difference between 1000000. and 1000001. is represent- able by the real type, but the difference between 1000000. and 1000000.01 is not. To avoid these kinds of arithmetic problems, it is usually better to replace our original loop with something like DO 10 it=0,10 X=0.0+0.1*it ... 10 This may not produce exactly the same results as the original loop, but in cases where they differ, this result is likely to be more accurate and more portable. (If you want to be extra careful, make it X=MIN(0.0+0.1*it,1.0).) Although computed GO TO is _not_ on the list of obsolescent features, there has also been some discussion of eventually replacing it with the CASE construct (some time in the next century). I would note the following: * In my experience, most uses of computed GO TO are to simulate CASE constructs, although in many cases this is masked by one of the cases being something like an EXIT or CYCLE of a loop. Obviously, in these cases it would be more appropriate to use the CASE construct once it is available. * In those cases where a computed GO TO cannot be construed as implementing a CASE construct, it is possible to simulate its effect by putting unconditional GO TO statements inside a CASE construct. . If the number of different branches is significantly smaller than the number of different case values, the CASE construct representation may still be more readable than a computed GO TO with repeated labels in the list. . Even in those cases where the CASE representation is more verbose and less readable, it should always possible. The size of a computed GO TO is limited by the number of allowed continuation lines, but a CASE construct consists of multiple statement and is thus not subject to this limit. If, in the interests of making the language smaller, we could retain only one of these features in the language, I would choose the CASE statement because it appears to be more appropriate more often and would involve no loss of functionality in those cases where it is not more appropriate. Fortunately, however, such a decision, if it ever needs to be made, is decades away. Kurt W. Hirchert hirchert@ncsa.uiuc.edu National Center for Supercomputing Applications