Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!husc6!hao!ames!amdahl!dlb!megatest!djones From: djones@megatest.UUCP Newsgroups: comp.lang.c Subject: Re: How are local vars allocated? Message-ID: <1633@megatest.UUCP> Date: Thu, 19-Nov-87 14:26:47 EST Article-I.D.: megatest.1633 Posted: Thu Nov 19 14:26:47 1987 Date-Received: Sun, 22-Nov-87 21:20:01 EST References: <9367@mimsy.UUCP> Organization: Megatest Corporation, San Jose, Ca Lines: 93 in article <9367@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) says: > > In article <7401@prls.UUCP> gardner@prls.UUCP (Robert Gardner) writes: >>Is there any danger of stack overflow with the following construct: >>for(;;) { >> int k; >> etc. etc. >>} > > No. > >>In other words, is k allocated only once at the beginning of the >>procedure containing this construct, or is it allocated each time >>the {} block is entered? Is the answer implementation dependent? > > The answer is implementation dependent, but if a loop like > > for (;;) { > int k; > } > > runs for several minutes, then produces a stack overflow, the > implementation is horrible. For example, a very straightforward > compiler might generate this: > > proc() > { > int a, b; > > for (;;) { > int k; > if (g()) > break; > } > a = 1; > } > -------- > _proc: > sub $8,sp | create local variables a, b > L1: > sub $4,sp | create local variable k > call _g | run g > tst r0 | what was g's return value? > bne L3 | nonzero, break loop > L2: > add $4,sp | destroy local variable k > bra L1 | back around the loop > L3: > add $4,sp | destroy local variable k > mov $1,-4(sp) | a = 1 > L0: > add $8,sp | destroy locals a, b > ret > > Label `L2' above is for a `continue' that might appear inside > the for loop. It is not used, but so what? Likewise, L0 is > allocated at the beginning of code generation for proc(), in > case there are any `return' statements in it. I optimised away > the sequence a truly dumb compiler would probably emit for > `if (g()) break'. > -- > In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) > Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris I wasn't going to answer, but this is just TOO silly. (Don't feel bad. The world needs some silliness from time to time.) 8-] The answer is, "No the stack will not overflow." If an explanation is required, it might be, "The variable k retains its value on each iteration, so no copy of it is needed. (Procedure local variables, unlike in FORTRAN for example, are not retained between procedure activations, and so new memory for them must typically be allocated on the stack.)" By the way, some compilers will produce code to use only one memory cell for all the variables k (one per procedure activation) implied by the execution of the following procedure, even when k > 0. It's called "removing tail-recursion." Wow. :-) foo(k) { if(k==0) return; else { /* etc. */ foo(k-1); } }