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