[net.lang.f77] Recursion bug in f77

mam@charm.UUCP (Matthew Marcus) (02/28/84)

In the writeup on f77 (Bell labs abortion), it states that "procedures may
call themselves, directly or through a chain of other procedures". This works
fine if foo only calls foo once.  I tried my hand at recursive graphics in
which a "figure" is defined as some mess of points and a number of smaller,
distorted "figures", down to the point where the "figure" became small.
This involved a procedure foo soing some stuff and calling foo several times
with assorted parameters.  f77 got confused and didn't go down all the branches
of the tree it was supposed to.  My last effort along this line was an f77
recode of a C program.  It was almost line-for-line identical, yet the C
worked fine, and the f77 didn't. My guess is that the stack is not treated
quite right in f77.  Part of the C program is shown below: (I nuked the f77)
float tol,xx1,xx2,yy1,yy2;
main()
{
float xb[5],yb[5];
double xl,xh,yl,yh;
int opt;
xl=yl=0.;
xh=yh=1.;
printf("Enter tol:");scanf("%f",&tol);
xb[0]=xb[4]=yb[0]=yb[4]=yb[1]=xb[3]=0.;
xb[1]=xb[2]=yb[2]=yb[3]=1.;
opt=NOCLEAR+NOAXES;
xx1=yy1=0.;
xx2=yy2=1.;
qkdraw(5,xb,yb,opt,&xx1,&xx2,&yy1,&yy2);
carpet(xl,xh,yl,yh);
}

carpet(xl,xh,yl,yh)
double xl,xh,yl,yh;
{
int opt;
float xb[5],yb[5];
double xx13,xx23,yy13,yy23,o3,t3;
int n;
o3=.333333333333333;
t3=.6666666666666666;
if( (xh-xl)>tol)
	{
	xx13=xl*t3+xh*o3;xx23=xh*t3+xl*o3;
	yy13=yl*t3+yh*o3;yy23=yh*t3+yl*o3;
	xb[0]=xb[4]=xb[3]=xx13;
	yb[1]=yb[0]=yy13;
	xb[1]=xb[2]=xx23;
	yb[2]=yb[3]=yy23;
	yb[4]=yy13;
	opt=NOCLEAR+NOAXES;
	n=5;
	qkdraw(n,xb,yb,opt,&xx1,&xx2,&yy1,&yy2);
	carpet(xl,xx13,yl,yy13);
	carpet(xl,xx13,yy13,yy23);
	carpet(xl,xx13,yy23,yh);
	carpet(xx13,xx23,yy23,yh);
	carpet(xx23,xh,yy23,yh);
	carpet(xx23,xh,yy13,yy23);
	carpet(xx23,xh,yl,yy13);
	carpet(xx13,xx23,yl,yy13);
	}
}

Here, qkdraw is a library routine for graphics -works for f77 and C.
This program works in C, drawing a stage of the "Sierpinski carpet", one
of the simpler fractals, which is made of squares of ever-decreasing sizes.
In f77, it draws only a few squares, because once carpet calls carpet, it
seems to be stuck there, and doesn't return for the second call to carpet.
	Sorry I can't provide the f77, but if you copy this program in
ratfor, you will come up with a losing f77 program - I guarantee it.
I hope this bug is fixed in 4.2bsd, as well as assorted other gripes.
I feel the butane starting to flow, so I'd better sign off before I roast
my terminal.

	{BTL}!charm!mam

mam@charm.UUCP (Matthew Marcus) (02/28/84)

OOPS! that's 'doing', not 'soing'. Also, that's the whole C program, not
just part of it.  If anybody's interested in fortran graphics, I'll be glad
to send the info about qkdraw (which I didn't write, don't get the wrong
idea). Sorry about that, chief!
	{BTL}!charm!mam

ka@hou3c.UUCP (Kenneth Almquist) (02/28/84)

Two things which you have to watch out for when converting between C
and FORTRAN are:
1)  In C, parameters are passed by value, while in FORTRAN they are
    passed by reference.
2)  In C, local variables are by default allocated dynamicly each time
    a routine is entered.  In FORTRAN, it is customary to allocate all
    local variables before the execution of the program begins.

I expect that the problem in the example is a result of (2).  The
solution is to declare all the local variables to be automatic.
(The automatic declaration is a UN*X extension to FORTRAN.)  That
way, you will get a new set of local variables each time the routine
invokes itself recursively, instead of sharing one copy between all
the invocations of the routine.
					Kenneth Almquist