[comp.lang.fortran] FORTRAN porting question

kaul@icarus.eng.ohio-state.edu (Rich Kaul) (04/04/89)

I've been given the dubious honor of porting some rather awful FORTRAN
code that someone wrote for our Suns to the HP300s we have around
here.  My question involves how a particular instruction should
behave.  The code I have to port has lots of loops like:
	IF (I.EQ.J) GOTO 1000
	...
	DO 1000 K=1,77
	...
   1000 CONTINUE

My question is, how should this behave?  I don't think this is good
FORTRAN (I already told you my opinion of the code), but it's been
quite a while since I've done any serious FORTRAN hacking.  The Sun
f77 compiler takes this construction happily, but the HP compiler
complains loudly and dies.

-rich

-=-
Rich Kaul			  | Richard Daley, Jr. is the front runner
The Ohio State University	  | for mayor of Chicago.  If recent history
2015 Neil Ave, Columbus, OH 43210 | is a guide, he will at least get his
kaul@icarus.eng.ohio-state.edu    | father's vote.

jlg@lanl.gov (Jim Giles) (04/04/89)

From article <1868@quanta.eng.ohio-state.edu>, by kaul@icarus.eng.ohio-state.edu (Rich Kaul):
> 	IF (I.EQ.J) GOTO 1000
> 	...
> 	DO 1000 K=1,77
> 	...
>    1000 CONTINUE

Try doing:

C     HOPE THIS IS THE ONE YOU WANT, THE OTHER IS MUCH HARDER
      IF (I.EQ.J) GOTO 1001
      ...
      DO 1000 K=1,77
      ...
 1000 CONTINUE
 1001 CONTINUE

If this fails to perform like you require, Try the following:

C     NOTE: THIS ONE MAY FAIL DUE TO K BEING UNDEFINED AT THIS POINT.
      IF (I.EQ.J) GOTO 1000
      ...
      K=0
  999 K=K+1
      ...
 1000 IF (K.LT.77) goto 999

These two sequences correspond to the only common 'extensions' to Fortran
which allow the GOTO in your original example.  Note that the original
is non-standard, so you can't really expect any consistent behaviour
from it.

chris@mimsy.UUCP (Chris Torek) (04/04/89)

In article <11447@lanl.gov> jlg@lanl.gov (Jim Giles) suggests two
alternatives to
>> 	IF (I.EQ.J) GOTO 1000
>> 	...
>> 	DO 1000 K=1,77
>> 	...
>>    1000 CONTINUE

the first being to go around the loop (I give about a 20% chance
to this being what the original coder---that is, the one who put
in the goto---intended), the second being

>C     NOTE: THIS ONE MAY FAIL DUE TO K BEING UNDEFINED AT THIS POINT.
>      IF (I.EQ.J) GOTO 1000
>      ...
>      K=0
>  999 K=K+1
>      ...
> 1000 IF (K.LT.77) goto 999

(minor bug: should be k .le. 77); I give this one a 30% chance of
being what the original coder intended.  But there is a third
alternative:

	if (i .eq. j) goto 999
	...
	k = 1
    998 ...
    999 k = k + 1
   1000 if (k .le. 77) goto 998

I give this one a 30% chance of being what the original coder
intended.

If you add up these chances, you will see a `missing' 20%.

I give that to the possibility that the original coder did not
mean any of these after all: that the original `if i==j' is a bug.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

session@uncw.UUCP (Zack Sessions) (04/04/89)

In article <1868@quanta.eng.ohio-state.edu> kaul@icarus.eng.ohio-state.edu (Rich Kaul) writes:
>
>...  The code I have to port has lots of loops like:
>	IF (I.EQ.J) GOTO 1000
>	...
>	DO 1000 K=1,77
>	...
>   1000 CONTINUE
>
>My question is, how should this behave?  ...

I would think that if the code took the goto 1000, that the loop would not
be executed, and control would simply pass to the next statement after the
continue. I agree, it is not very clean coding, and would personally have done
it differently. The statement number referenced in the do statement does not
have to be a continue statement, it can be any executable statement.

Zack Sessions

cunniff@hpfcdc.HP.COM (Ross Cunniff) (04/04/89)

(regarding code like:
	IF (I .EQ. J) GOTO 1000
	DO 1000 K=1,77
1000	CONTINUE

hideous though it may be)

In all releases after and including 5.5, the HP-UX S300 f77 compiler
has had an option, +E0, that allows this construct (although it will
emit a warning about 'jump into block from line x').  Note that there
is no 'correct' interpretation of this code, so the actual behaviour
of the code is system dependent, even if it successfully compiles.

If you are interested in cross-vendor compatibilty and you do not
have the latest version (soon to be 6.5) of the compiler, contact
your local HP sales office to get an update; the later releases
have contained substantial portability enhancements as well as
greatly improved optimization and development environment enhancements.

				Ross Cunniff
				Hewlett-Packard Colorado Languages Lab
				...{ucbvax,hplabs}!hpfcla!cunniff
				cunniff%hpfcrt@hplabs.HP.COM

mccalpin@loligo.uucp (John McCalpin) (04/05/89)

In article <1868@quanta.eng.ohio-state.edu> kaul@icarus.eng.ohio-state.edu (Rich Kaul) writes:
>...  The code I have to port has lots of loops like:
>	IF (I.EQ.J) GOTO 1000
>	...
>	DO 1000 K=1,77
>	...
>   1000 CONTINUE
>My question is, how should this behave?  ...

Although this particular horse has been beaten to death, I just thought I
should throw in a loop that occurred frequently in a code that I got to
port once.

	if ( count.ge.1 ) goto 1000
	do 1000 i=1,count
	    do stuff here
 1000	continue

This was apparently an attempt to enable Fortran-77 style DO loops 
with a Fortran-66 compiler.  Of course, in the modern world, it just
manages to combine a redundant loop bounds check with an illegal jump.
I'm sure that the programmer thought it was clever, though....
----------------------   John D. McCalpin   ------------------------
Dept of Oceanography & Supercomputer Computations Research Institute
mccalpin@masig1.ocean.fsu.edu		mccalpin@nu.cs.fsu.edu
--------------------------------------------------------------------

jlg@lanl.gov (Jim Giles) (04/05/89)

From article <16715@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek):
> In article <11447@lanl.gov> jlg@lanl.gov (Jim Giles) suggests two
>>C     NOTE: THIS ONE MAY FAIL DUE TO K BEING UNDEFINED AT THIS POINT.
>>      IF (I.EQ.J) GOTO 1000
>>      ...
>>      K=0
>>  999 K=K+1
>>      ...
>> 1000 IF (K.LT.77) goto 999
> 
> (minor bug: should be k .le. 77) [...]

Not true.  If the condition were set to (K.LE.77) instead of (K.LT.77),
the body of the loop would be executed with K==78.  That would be one too
many times.  You are right, however, that the more common desired inter-
pretation of the loop would be:

C     NOTE: THIS ONE MAY FAIL DUE TO K BEING UNDEFINED AT THIS POINT.
      IF (I.EQ.J) GOTO 1000
      ...
      K=1
  999 ...       ! BODY OF LOOP
      K=K+1
 1000 IF (K.LE.77) goto 999

The reason for prefering this would be that the value of K after the
loop would be 78, just like the DO-loop would have left.

steve@oakhill.UUCP (steve) (04/05/89)

In article <1868@quanta.eng.ohio-state.edu>, kaul@icarus.eng.ohio-state.edu
			(Rich Kaul) writes:
> 
> I've been given the dubious honor of porting some rather awful FORTRAN
> code that someone wrote for our Suns to the HP300s we have around
> here.  My question involves how a particular instruction should
> behave.  The code I have to port has lots of loops like:
> 	IF (I.EQ.J) GOTO 1000
> 	...
> 	DO 1000 K=1,77
> 	...
>    1000 CONTINUE
> 
> My question is, how should this behave?  I don't think this is good

This is a test to see if I crawl out from under my rock to talk about this,
right? :-) (actually I know better, but this is a variant of one of our never-
dying discussions).

This code is not portable.  It is not good code.  It is not standard
conforming (see I do say this :-)). I know of at least two major
compilers that will generate an infinite loop in this code.  Therefore
it is not even portable.  It is probable that the writer wanted to jump
over the loop, therefore

       IF (I.EQ.J) GOTO 1001
       ...
       DO 1000 K=1,77
       ...
 1000 CONTINUE
 1001 CONTINUE

is probably what is called for.  If analysis of the code shows that the
writer wanted to jump into the loop.  You must do the loop manually:

      IF (I.EQ.J) GOTO 1000
      ...
      K = 1
 1001 ...
      ...
 1000 CONTINUE
      K = K + 1
      IF (K.LE.77) GOTO 1001

But be aware in this second case.  K is undefined at 1000 if the first
jump is taken unless K is defined elsewhere.

                   enough from this mooncalf - Steven
----------------------------------------------------------------------------
To flame someone for bad spelling or grammer is a discouragement to net
discussion in a timely fashion.
----------------------------------------------------------------------------
These opinions aren't necessarily Motorola's or Remora's - but I'd like to
think we share some common views.
----------------------------------------------------------------------------
Steven R Weintraub                        cs.utexas.edu!oakhill!devsys!steve
Motorola Inc.  Austin, Texas 
(512) 440-3023 (office) (512) 453-6953 (home)
----------------------------------------------------------------------------

kaul@icarus.eng.ohio-state.edu (Rich Kaul) (04/05/89)

In article <1951@devsys.oakhill.UUCP> steve@oakhill.UUCP (steve) writes:
>This is a test to see if I crawl out from under my rock to talk about this,
>right? :-) (actually I know better, but this is a variant of one of our never-
>dying discussions).

I don't give tests.  I take them.  *sigh*

>This code is not portable.  It is not good code.  It is not standard
>conforming (see I do say this :-)). I know of at least two major
>compilers that will generate an infinite loop in this code.  Therefore
>it is not even portable.

That seems to be the consensus of most of these writers and what I
thought was the case when I posted this question.  I thought it rather
bad coding style (much of the other code in this package is worse).

This code actually appears in a package that a company who caters to
VMS VAXen sold us.  We made the mistake of buying their "port" to the
Suns, so I really do have some trouble talking to the originators of
the code to see what their intentions were.  Further, the only VMS VAX
we have around here is so loaded that just getting logged on can be an
accomplishment.  Another reason to go with the HPs and Suns.

As it turns out, I just went in and duplicated the behavior of the Sun
compiler, which did loop, but started with k=2 in the loop.  The
program seems to work, but I have told people not to expect miracles
and to double check their work :-)

I'd like to thank everybody for their help.  It really helps to have a
good place to ask questions like this, especially since FORTRAN is not
my primary programming language.  At least, not since the PDP-11 under
RT-11 got dumped.

-rich

-=-
Rich Kaul			  | Richard Daley, Jr. is the front runner
The Ohio State University	  | for mayor of Chicago.  If recent history
2015 Neil Ave, Columbus, OH 43210 | is a guide, he will at least get his
kaul@icarus.eng.ohio-state.edu    | father's vote.

shapiro@rb-dc1.UUCP (Mike Shapiro) (04/06/89)

In article <330@uncw.UUCP> session@uncw.UUCP (Zack Sessions) writes:
>In article <1868@quanta.eng.ohio-state.edu> kaul@icarus.eng.ohio-state.edu (Rich Kaul) writes:
>>
>>...  The code I have to port has lots of loops like:
>>	IF (I.EQ.J) GOTO 1000
>>	...
>>	DO 1000 K=1,77
>>	...
>>   1000 CONTINUE
>>
>>My question is, how should this behave?  ...
>
>I would think that if the code took the goto 1000, that the loop would not
>be executed, and control would simply pass to the next statement after the
>continue. I agree, it is not very clean coding, and would personally have done
>it differently. The statement number referenced in the do statement does not
>have to be a continue statement, it can be any executable statement.
  ...

Again in this discussion thread, I think it's important that we
remember the rules of the Fortran game (no matter what we think of
them):

	11.10.8  _Transfer into the Range of a DO-loop_.  Transfer of
	control into the range of a DO-loop from outside the range
	is not permitted.

The above quote is from page 11-9 (lines 15-17) of ANSI X3.9-1978
FORTRAN 77.

The range of a DO-loop consists of all the executable statements that
appear following the DO statement that specifies the DO-loop, up to
and including the terminal statement of the DO-loop.  (page 11-6,
lines 26-29).

Since the code violates the rules, it is not a valid FORTRAN 77
program.  The interpretation noted is probably correct, but you will
need to verify this by finding out what compiler the code was
originally written for and then finding out how that FORTRAN compiler
handled this FORTRAN-like non-FORTRAN code.

-- 

Michael Shapiro, Gould/General Systems Division (soon to be Encore)
15378 Avenue of Science, San Diego, CA 92128
(619)485-0910    UUCP: ...sdcsvax!ncr-sd!rb-dc1!shapiro

khb@fatcity.Sun.COM (Keith Bierman Sun Tactical Engineering) (04/06/89)

In article <1868@quanta.eng.ohio-state.edu> kaul@icarus.eng.ohio-state.edu (Rich Kaul) writes:
>
>I've been given the dubious honor of porting some rather awful FORTRAN
>...

>	IF (I.EQ.J) GOTO 1000
>	...
>	DO 1000 K=1,77
>	...
>   1000 CONTINUE
>
>My question is, how should this behave?  I don't think this is good
>ORTRAN 

You are right. It's not.

	if (i .ne.  j) then
	   do k = 1, 77
	      ...
	   end do
	end if

Is cleaner. The HP might require do 1000 rather than using the f88
style loop.
Keith H. Bierman
It's Not My Fault ---- I Voted for Bill & Opus