2014_5001@uwovax.uwo.ca (09/21/89)
I was trying to compile FLEX with TurboC 2.0. Not having a yacc, I ran bison on parse.y. With a minor change in the source, I managed to get the whole thing compiled. Unfortunately, it requests the presence of an alloca() routine, apparently with a prototype like: void *alloca(size_t s); (As well as I can tell from the context and the type casting). It does not appear to figure in parse.y, so it appears likely to me that it is put in by my bison. What does alloca() do? It does not appear in the TurboC 2.0 library, nor in Unix SysV man pages. -- Alexander Pruss, at one of: Department of Applied Mathematics, Astronomy, Mathematics, or Physics University of Western Ontario pruss@uwovax.uwo.ca pruss@uwovax.BITNET A5001@nve.uwo.ca
henry@utzoo.uucp (Henry Spencer) (09/24/89)
In article <3823.2518c141@uwovax.uwo.ca> 2014_5001@uwovax.uwo.ca writes: >... What does alloca() do? >It does not appear in the TurboC 2.0 library, nor in Unix SysV >man pages. It's a nonstandard botch (originating in some poorly-designed ancient Unix systems) that some of the Gnoids are really fond of. The theory is that it's malloc() except that the storage automatically goes away when you leave the function it was called in. This is more than a little difficult to implement on some machines... -- "Where is D.D. Harriman now, | Henry Spencer at U of Toronto Zoology when we really *need* him?" | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
mike@thor.acc.stolaf.edu (Mike Haertel) (09/25/89)
In article <1989Sep24.050214.13898@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >In article <3823.2518c141@uwovax.uwo.ca> 2014_5001@uwovax.uwo.ca writes: >>... What does alloca() do? >>It does not appear in the TurboC 2.0 library, nor in Unix SysV >>man pages. > >It's a nonstandard botch (originating in some poorly-designed ancient Unix >systems) that some of the Gnoids are really fond of. The theory is that >it's malloc() except that the storage automatically goes away when you leave >the function it was called in. This is more than a little difficult to >implement on some machines... I'm glad you said "SOME OF the Gnoids" (emphasis mine), Henry. Not all of us are particularly fond of alloca(). I think alloca() originated in one of the early VAX BSD's. My guess would be that it was invented for use implementing Franz Lisp, and somehow wormed its way into the standard library during a lapse of judgement on someone's part. The practical problem with alloca() is that it cannot be implemented on machines without a frame pointer (except by compiler hack) and therefore is not available in all environments. There are philosophical objections too, but I won't go into them. Unfortunately, alloca() is sometimes necessary in programs that call longjmp(). (longjmp(), like alloca(), is evil. Even though it is in the C standard.) But two wrongs do not make a right . . . Doug Gwyn (gwyn@smoke.brl.mil) has a semi-portable fake alloca() written in C that people without alloca() may find useful when installing GNU software on their machines. -- Mike Haertel <mike@stolaf.edu> ``There's nothing remarkable about it. All one has to do is hit the right keys at the right time and the instrument plays itself.'' -- J. S. Bach
henry@utzoo.uucp (Henry Spencer) (09/26/89)
In article <6361@thor.acc.stolaf.edu> mike@stolaf.edu (Mike Haertel) writes: >>>... What does alloca() do? >>It's a nonstandard botch (originating in some poorly-designed ancient Unix >>systems) that some of the Gnoids are really fond of... >I think alloca() originated in one of the early VAX BSD's. My guess >would be that it was invented for use implementing Franz Lisp... It goes back farther than that. The first occurrence I'm aware of was in PWB circa 1977. (PWB was a pdp11 Unix variant, sort of a neolithic ancestor of System V.) It showed up in SCCS (PWB's biggest, uh, contribution to the user interface) in particular. -- "Where is D.D. Harriman now, | Henry Spencer at U of Toronto Zoology when we really *need* him?" | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
2014_5001@uwovax.uwo.ca (09/26/89)
In article <3823.2518c141@uwovax.uwo.ca>, 2014_5001@uwovax.uwo.ca writes: > I was trying to compile FLEX with TurboC 2.0. Not having a yacc, I > ran bison on parse.y. > > With a minor change in the source, I managed to get the whole thing > compiled. Unfortunately, it requests the presence of an alloca() > routine, apparently with a prototype like: > void *alloca(size_t s); > (As well as I can tell from the context and the type casting). > It does not appear to figure in parse.y, so it appears likely to me > that it is put in by my bison. What does alloca() do? > It does not appear in the TurboC 2.0 library, nor in Unix SysV > man pages. I rarely follow up on my own articles, but here goes.. I have used the following alloca() implementation for the ibm pc (highly unportable): ----- alloca.h---- static unsigned int _INtERNAL_alloca_; #define alloca(x) \ ( _INtERNAL_alloca_=_SP, _SP-=(x), (void *)_INtERNAL_alloca_ ) ----- I am wondering whether this does what alloca() should do. Have I missed something? Turbo C apparently allocates stack space for all the blocks in a function once at the top. i.e. given void f(void) { int a; { int b; } }, space for both a and b will be allocated at the top of the function, and deallocated upon return. This means that since my alloca() macro relies on the automatic var deallocation, the space will be in use until a return. -- Alexander Pruss, at one of: Department of Applied Mathematics, Astronomy, Mathematics, or Physics University of Western Ontario pruss@uwovax.uwo.ca pruss@uwovax.BITNET A5001@nve.uwo.ca
bill@twwells.com (T. William Wells) (09/27/89)
In article <1989Sep24.050214.13898@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
: It's a nonstandard botch (originating in some poorly-designed ancient Unix
: systems) that some of the Gnoids are really fond of. The theory is that
: it's malloc() except that the storage automatically goes away when you leave
: the function it was called in. This is more than a little difficult to
: implement on some machines...
The version of gas (Gnu assembler) I have uses alloca in two places;
neither of which is a particularly good place for it and one of which
is downright stupid. That latter is alloca'ing an array which can
never be over four bytes long. I found these because I won't use code
that uses alloca. And maybe when gas actually works on my system (its
opcode tables are incomplete), I'll actually use it.
---
Bill { uunet | novavax | ankh | sunvice } !twwells!bill
bill@twwells.com
djones@megatest.UUCP (Dave Jones) (09/27/89)
From article <6361@thor.acc.stolaf.edu>, by mike@thor.acc.stolaf.edu (Mike Haertel):
> longjmp(), like alloca(), is evil.
I like longjmp() and alloca(). But then, I guess I like a lot of
evil things, come to think of it.
barmar@kulla (Barry Margolin) (09/27/89)
In article <1989Sep25.172824.18692@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >In article <6361@thor.acc.stolaf.edu> mike@stolaf.edu (Mike Haertel) writes: >>I think alloca() originated in one of the early VAX BSD's. My guess >>would be that it was invented for use implementing Franz Lisp... >It goes back farther than that. The first occurrence I'm aware of was in >PWB circa 1977. It also exists in Multics, although I don't know whether it was in the Multics design during the days when Bell Labs was part of the project. On Multics it is called something like cu_$expand_stack_frame ("cu_$" is the prefix for the "command utilities" library, which includes lots of stack-frame-manipulation routines because it contains the variable-argument routines that are used instead of argv[], and the generate-call routines that are used in place of exec()). Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
Don_A_Corbitt@cup.portal.com (09/29/89)
The alloca() you posted for Turbo C will usually work. Notably, it will not work for some floating point code - TC 'knows' how far the stack pointer is from the frame pointer. It subtracts from the stack pointer, then stores relative the frame pointer. If you have alloca()'ed, it don't work no good. Don_A_Corbitt@cup.portal.com "Trying for next month's bandwidth-waster posting"
bga@bgalli.eds.com (Billy G. Allie) (10/04/89)
In article <3839.251f4ecf@uwovax.uwo.ca>, 2014_5001@uwovax.uwo.ca writes: > I have used the following alloca() implementation for the ibm pc > (highly unportable): > > ----- alloca.h---- > static unsigned int _INtERNAL_alloca_; > #define alloca(x) \ > ( _INtERNAL_alloca_=_SP, _SP-=(x), (void *)_INtERNAL_alloca_ ) > ----- > > I am wondering whether this does what alloca() should do. > Have I missed something? The macro you gave above will fail in any of the large data models. Also, your macro could leave the stack pointer pointing to an odd address, some- thing that the 80x86 processors do not like. I am including the source for the macro that I wrote when I ported BISON to the MS-DOS operating system and the Turbo-C compiler. It will work correctly for any data model. -------------------------------><Cut Here><------------------------------- # To unbundle, sh this file echo alloca.h 1>&2 cat >alloca.h <<'End of alloca.h' /***********************************************************************\ | The following gives the definition of a macro (alloca) that allocates | | space like malloc EXCEPT that it is allocated from the stack and does | | not have to be freed. The allocated space will automatically disap- | | pear when the function that allocated the space exits. | | | | W*A*R*N*I*N*G | | This code is VERY compiler dependant and will only work for Turbo C | | versions 1.5 and 2.0. You are forwarned. | | | | This code is released into the public domain. | \***********************************************************************/ #if !defined(alloca) #if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) #define alloca(i) (_SP-=((i+1)&0xFFFE),(void *)(((unsigned long)_SS<<16)|_SP)) #else #define alloca(i) (_SP-=((i+1)&0xFFFE),(void *)_SP) #endif #endif End of alloca.h -------------------------------><Cut Here><------------------------------- -- ____ | Billy G. Allie | Internet..: bga@bgalli.eds.com | /| | 7436 Hartwell | UUCP......: uunet!{mcf|edsews}!bgalli!bga |-/-|----- | Dearborn, MI 48126 | Compuserve: 76337,2061 |/ |LLIE | (313) 582-1540 | Genie.....: BGALLIE
dave@dsi.COM (Dave Rifkind) (10/06/89)
In article <417@bgalli.eds.com> bga@bgalli.eds.com (Billy G. Allie) writes:
: I am including the source for
:the macro that I wrote when I ported BISON to the MS-DOS operating system
:and the Turbo-C compiler. It will work correctly for any data model.
...
:#if !defined(alloca)
:#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
:#define alloca(i) (_SP-=((i+1)&0xFFFE),(void *)(((unsigned long)_SS<<16)|_SP))
:#else
:#define alloca(i) (_SP-=((i+1)&0xFFFE),(void *)_SP)
:#endif
:#endif
Just be careful not to use this in a function with very few local
variables. If Turbo C does not have to adjust the stack pointer (to
allocate locals) in the function prologue, it will not generate a "mov
sp, bp" in the return sequence. This would make returning from such a
function interesting, but not useful.