[comp.unix.wizards] libpw.a

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?