stailey@iris613.gsfc.nasa.gov (Ken Stailey) (04/08/89)
As far as I can guess libpw.a is the programmer's workbench library. Only a few of the many nifty looking function names (regcmp, etc) are documented. Can anyone explain why this is, or where to go to get docs? Ken
gwyn@smoke.BRL.MIL (Doug Gwyn ) (04/09/89)
In article <157@dftsrv.gsfc.nasa.gov> stailey@iris613.gsfc.nasa.gov (Ken Stailey) writes: >As far as I can guess libpw.a is the programmer's workbench library. >Only a few of the many nifty looking function names (regcmp, etc) are >documented. Can anyone explain why this is, or where to go to get docs? Please don't use libPW.a for anything other than maintenance of existing products until they can be converted to use standard C library routines. libPW.a is utterly obsolete (and generally poorly designed and coded).
les@chinet.chi.il.us (Leslie Mikesell) (04/10/89)
In article <10013@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >Please don't use libPW.a for anything other than maintenance of >existing products until they can be converted to use standard C >library routines. >libPW.a is utterly obsolete (and generally poorly designed and >coded). Does this mean that programmers shouldn't use alloca() or that a well designed and coded version should be put in the standard library? Les Mikesell
john@frog.UUCP (John Woods) (04/13/89)
In article <8184@chinet.chi.il.us>, les@chinet.chi.il.us (Leslie Mikesell) writes: > In article <10013@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: > >libPW.a is utterly obsolete (and generally poorly designed and > >coded). > > Does this mean that programmers shouldn't use alloca() or that a > well designed and coded version should be put in the standard > library? > Programmers shouldn't use alloca(). The standard implementation of allocating a chunk of stack is not applicable to all computer architectures or compilers, and the non-stack-based implementations require too much conspiracy and machination to be efficient and worthwhile. -- John Woods, Charles River Data Systems, Framingham MA, (508) 626-1101 ...!decvax!frog!john, john@frog.UUCP, ...!mit-eddie!jfw, jfw@eddie.mit.edu Healed Head BAD, Bleeding Head GOOD!
gordon@sneaky.UUCP (Gordon Burditt) (04/17/89)
>Programmers shouldn't use alloca(). The standard implementation of allocating >a chunk of stack is not applicable to all computer architectures or compilers, >and the non-stack-based implementations require too much conspiracy and >machination to be efficient and worthwhile. There is an even better reason not to use alloca(). I claim that there exists NO correct implementation of alloca() (in any released or unreleased version of anything) under these conditions: (1) Alloca is implemented using the stack. (not malloc() and some mechanism to keep track of what to free when), AND (2) The calling sequence is caller-pops-args, not callee-pops-args. AND, (3) The compiler doesn't implement alloca() as a built-in function (as opposed to only a function stuck in a library without special compiler knowledge of alloca(), which is hopeless). If you don't do (1), you are defeating the supposed advantages of alloca - speed, and either you have to do explicit freeing of memory somehow, or you might run out of memory sometime when you shouldn't. Most systems that don't do (2) have problems with old code because you have to actually follow the rules for varargs or stdargs to do variable-argument functions, or they break. You also need an instruction for "return and adjust stack". GCC has it as an option for the 68010, and the Vax can use it. Most compilers for various micros seem to use caller-pops-args. GCC implements alloca() as a built-in (assuming appropriate definitions in a header file), but still gets it wrong. The main problem here is that it is necessary to evaluate ALL arguments that involve alloca to a multi-argument function before pushing ANY of them. Before anyone starts yelling, "but mine works", try coming up with how the compiler is going to lay out the stack, considering function args and alloca-allocated memory, for the following code fragment. No fair putting everything in registers - if you have that many registers, then I'm going to keep doubling the number of args until you don't. Evaluating one arg (which calls alloca), pushing the result, then evaluating another arg (which calls alloca) is going to interleave arguments and allocated areas in a big mess, so when the function tries to look at its arguments, it gets uninitialized garbage. void *alloca(); /* please no void * vs. char * wars */ struct foo1 { .... }; struct foo2 { .... }; struct foo3 { .... }; struct foo4 { .... }; struct foo5 { .... }; struct bar { struct foo1 *a; struct foo2 *b; struct foo3 *c; struct foo4 *d; struct foo5 *e; }; struct bar initfunc(a, b, c, d, e) struct foo1 *a; struct foo2 *b; struct foo3 *c; struct foo4 *d; struct foo5 *e; { static struct bar ret; .... /* code fills in structures for a, b, c, d, and e */ ret.a = a; ret.b = b; ret.c = c; ret.d = d; ret.e = e; return ret; } main() { struct bar control; .... *(control = alloca(sizeof bar)) = initfunc( alloca(sizeof(struct foo1)), alloca(sizeof(struct foo2)), alloca(sizeof(struct foo3)), alloca(sizeof(struct foo4)), alloca(sizeof(struct foo5)) ); .... } Note: "...." means code has been left out; it is NOT a misspelling for a character sequence used in declaring ANSI varadic functions. Even if you do make the compiler know about alloca(), and rule that you can't use a pointer to alloca in a pointer-to-function to make function calls, the code can still get very messy and slow. If the compiler references auto variables as an offset from the stack pointer (rather than a frame pointer), all bets are off. If the compiler doesn't implement alloca as a built-in, you haven't a prayer of making even the simple cases work by writing a library function. Gordon L. Burditt ...!texbell!sneaky!gordon P.S. I have an implementation that sort-of works in the above example, provided you put a limit on the number of args. It wastes an amount of memory equal to the worst-case pushed args plus the worst-case saved registers ON EVERY CALL.
jb@aablue.UUCP (John B Scalia) (04/18/89)
In article <1250@frog.UUCP> john@frog.UUCP (John Woods) writes: >[deleted for brevity] >Programmers shouldn't use alloca(). The standard implementation of allocating >a chunk of stack is not applicable to all computer architectures or compilers, >and the non-stack-based implementations require too much conspiracy and >machination to be efficient and worthwhile. OK, I agree that libpw.a is pretty much worthless, but after your statement about alloca(), I've got another question. If programmers shouldn't use it, why did GNU require it for installing their grep facility? I'll admit that I haven't studied the code thoroughly, but their implementation doesn't seem that bad. -- A A Blueprint Co., Inc. - Akron, Ohio +1 216 794-8803 voice UUCP: {uunet!}aablue!jb Marriage is a wonderful institution, but who FidoNet: 1:157/697 wants to spend their life in an institution. EchoNet: US:OH/AKR.0
jfh@rpp386.Dallas.TX.US (John F. Haugh II) (04/18/89)
In article <9731@sneaky.UUCP> gordon@sneaky.UUCP (Gordon Burditt) writes: >>Programmers shouldn't use alloca(). The standard implementation of allocating >>a chunk of stack is not applicable to all computer architectures or compilers, >>and the non-stack-based implementations require too much conspiracy and >>machination to be efficient and worthwhile. > >There is an even better reason not to use alloca(). Yes, Gordon, you could have said it was broken in less than 105 lines. It is not safe to be screwing with the stack two different ways if both mechanisms are not fully aware of the others doings. I don't know if you could reasonably inline [ ala' GCC ] alloca() and have it ever work 100% using the example you provided. However, the simpler case of foo1 = alloca(heap1); foo2 = alloca(heap2); foo3 = alloca(heap3); barf(foo1, foo2, foo3); DOES work. -- John F. Haugh II +-Quote of the Week:------------------- VoiceNet: (214) 250-3311 Data: -6272 | "When everyone else compiles InterNet: jfh@rpp386.Dallas.TX.US | I will interpret." UucpNet : <backbone>!killer!rpp386!jfh +-- [ Not said by ] -- Doug Davis --
gwyn@smoke.BRL.MIL (Doug Gwyn) (04/18/89)
In article <564@aablue.UUCP> jb@aablue.UUCP (John B Scalia) writes: >OK, I agree that libpw.a is pretty much worthless, but after your statement >about alloca(), I've got another question. If programmers shouldn't use it, >why did GNU require it for installing their grep facility? Apparently RMS and possibly others on the GNU project think that there should be some form of garbage collection (LISP heritage showing?) and decided on alloca() as a way to get it. I argued from the start that it was a mistake to rely on alloca()...
rbj@dsys.icst.nbs.gov (Root Boy Jim) (04/19/89)
? From: Gordon Burditt <gordon@sneaky.uucp> ? There is an even better reason not to use alloca(). ? I claim that there exists NO correct implementation of alloca() (in any ? released or unreleased version of anything) under these conditions: ? (1) Alloca is implemented using the stack. (not malloc() and some ? mechanism to keep track of what to free when), AND ? (2) The calling sequence is caller-pops-args, not callee-pops-args. ? AND, ? (3) The compiler doesn't implement alloca() as a built-in function ? (as opposed to only a function stuck in a library without special ? compiler knowledge of alloca(), which is hopeless). ? If you don't do (1), you are defeating the supposed advantages of alloca - ? speed, and either you have to do explicit freeing of memory somehow, or ? you might run out of memory sometime when you shouldn't. Whereby you just call alloca(0) and if there is anything to clean up, you get it back. If you supply Doug Gwyn's alloca.c, you allow less capable machines to run the alloca infested code, albeit slower. ? Most systems that don't do (2) have problems with old code because ? you have to actually follow the rules for varargs or stdargs to do ? variable-argument functions, or they break. You also need an ? instruction for "return and adjust stack". GCC has it as an option ? for the 68010, and the Vax can use it. Most compilers for various micros ? seem to use caller-pops-args. I don't see the problem. Use the frame pointer. ? GCC implements alloca() as a built-in (assuming appropriate definitions ? in a header file), but still gets it wrong. The main problem here ? is that it is necessary to evaluate ALL arguments that involve alloca ? to a multi-argument function before pushing ANY of them. ? Before anyone starts yelling, "but mine works", try coming up with how the ? compiler is going to lay out the stack, considering function args and ? alloca-allocated memory, for the following code fragment.... ? *(control = alloca(sizeof bar)) = initfunc( alloca(sizeof(struct foo1)), ? alloca(sizeof(struct foo2)), alloca(sizeof(struct foo3)), ? alloca(sizeof(struct foo4)), alloca(sizeof(struct foo5)) ); ? Note: "...." means code has been left out; it is NOT a misspelling for ? a character sequence used in declaring ANSI varadic functions. Your code is meaningless. Alloca cannot be called in argument lists for the exact reasons you specify. ? Even if you do make the compiler know about alloca(), and rule that you ? can't use a pointer to alloca in a pointer-to-function to make function ? calls, the code can still get very messy and slow. ? If the compiler references auto variables as an offset from the stack ? pointer (rather than a frame pointer), all bets are off. If the compiler ? doesn't implement alloca as a built-in, you haven't a prayer of making ? even the simple cases work by writing a library function. Alloca is a special purpose beast. No reason to try and make it general. ? Gordon L. Burditt ? ...!texbell!sneaky!gordon Root Boy Jim is what I am Are you what you are or what?
jfh@rpp386.Dallas.TX.US (John F. Haugh II) (04/21/89)
In article <1883@thor.acc.stolaf.edu> mike@mike@stolaf.edu writes: >I'm the author of GNU grep, and I firmly believe that alloca is Evil. >Don't use it in new programs! The idea is wonderful. Not unlike the goto or middle-tested loops. It fills an emptiness, but requires some degree of discipline. >Many people know that Richard strongly advocates the use of alloca. >But just because Richard uses it in his programs doesn't mean it is >necessarily a good thing! It IS a nice concept. It would be nice if C had better garbage collection, like LISP. I always enjoyed SNOBOL and LISP programming because you use the stuff, then toss it, then use it again. In C and others, memory management is a CHORE. >To repeat: alloca is EVIL. It doesn't have to be. -- John F. Haugh II +-Quote of the Week:------------------- VoiceNet: (214) 250-3311 Data: -6272 | "When everyone else complies InterNet: jfh@rpp386.Dallas.TX.US | I will too ..." UucpNet : <backbone>!killer!rpp386!jfh +------------------- -- Doug Davis --
root@yale.UUCP (Root Of All Evil) (04/21/89)
In article <15945@rpp386.Dallas.TX.US> jfh@rpp386.Dallas.TX.US (John F. Haugh II) writes: <stuff deleted> >..... I always enjoyed SNOBOL and LISP programming >because you use the stuff, then toss it, then use it again. In C >and others, memory management is a CHORE. C is not a language to do string processing in. C is designed to be efficient for SYSTEMS programming. Do we really want garbage collection in the language used for the kernal of the operating system? Sounds pretty silly to me. If you want to program in Lisp, program in Lisp. Don't expect C to provide you with a Lisp environment. -Scott Berryman berryman@CS.YALE.EDU
bzs@bu-cs.BU.EDU (Barry Shein) (04/23/89)
>It IS a nice concept. It would be nice if C had better garbage >collection, like LISP. I always enjoyed SNOBOL and LISP programming >because you use the stuff, then toss it, then use it again. In C >and others, memory management is a CHORE. > >>To repeat: alloca is EVIL. > >It doesn't have to be. >-- >John F. Haugh II +-Quote of the Week:------------------- Some Pascals (maybe all?) supported a possible compromise where you called a routine "mark()", did your allocs and later some sort of super-free which would release everything back to the last mark() call. There was no need to call all in the same routine, just so long as mark() was called earlier than the allocs and free. It could work either stackwise (my preference) or take some sort of magic cookie to identify which mark to clear back to (probably useful before a longjmp after an error condition.) This should be very easy to implement within C/Unix, even within the current malloc schemes by just introducing a special mark cell into the chain. -- -Barry Shein, Software Tool & Die There's nothing more terrifying to hardware vendors than satisfied customers.
rbj@dsys.icst.nbs.gov (Root Boy Jim) (05/02/89)
? From: Root Of All Evil <root@yale.uucp>
? jfh@rpp386.Dallas.TX.US (John F. Haugh II) writes:
? <stuff deleted>
? >..... I always enjoyed SNOBOL and LISP programming
? >because you use the stuff, then toss it, then use it again. In C
? >and others, memory management is a CHORE.
? C is not a language to do string processing in. C is designed to
? be efficient for SYSTEMS programming. Do we really want
? garbage collection in the language used for the kernal of the operating
? system? Sounds pretty silly to me. If you want to program in Lisp, program
? in Lisp. Don't expect C to provide you with a Lisp environment.
If GC can be done by adding a constant to the stack pointer (or copying
the frame pointer), then yes, I want it in the kernel. In that case,
alloca is more efficient than malloc/free. Think about it.
And while we're at it, unwind-protect and catch/throw are cleaner
than setjmp/longjmp as well. Sigh, maybe in C++++.
? -Scott Berryman
? berryman@CS.YALE.EDU
Root Boy Jim is what I am
Are you what you are or what?