Path: utzoo!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!zaphod.mps.ohio-state.edu!usc!elroy.jpl.nasa.gov!ncar!gatech!purdue!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: alloca() portability Keywords: portability, alloca Message-ID: <27608@mimsy.umd.edu> Date: 12 Nov 90 06:06:35 GMT References: <14377@smoke.brl.mil> <9122@ncar.ucar.edu> <27537@mimsy.umd.edu> <1990Nov09.233527.7489@chinet.chi.il.us> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 88 In article <1990Nov09.233527.7489@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes, not in quite this order: >This does handle recursion and longjmp()'s out of signal handlers As soon as you mention `longjmp out of signal handlers' you have left either portability or reliability far behind (even if you are careful, doing *anything* with signals tends to make software unportable). In article <27537@mimsy.umd.edu> I wrote: >>All in all, I would say that the threat of failure (from optimizing >>compilers) plus that of nonportability (to environments where not even >>a mallocking alloca can be used) far outweigh the convenience of >>not having to call free(). All that is left is the difference in >>speed, and there are simple ways around that problem as well. >The usual "simple" way goes something like this: > >work(str) >char *str; >{ > buffer[BIG_BUFF]; > strcpy(buffer,str); /* make a local copy to manipulate */ No, actually, I was thinking of one of these: void foo(int n) { static char *space; static size_t size; size_t need = compute_space_needed(n); if (size < need) { space = space ? realloc(space, need) : malloc(need); if (space == NULL) ... handle no space ... size = need; } ... } or void foo(int n) { char *space; size_t need = compute_space_needed(n); char local[SMALL]; if (need <= SMALL) space = local; else { space = malloc(need); if (space == NULL) ... handle no space ... } ... cannot simply `return' here ... if (space != local) /* equiv, need > SMALL */ free(space); } >[Using alloca()] does handle recursion The second form above handles recursion; the first does not, but is more efficient in some cases, and is somewhat easier to code (since all the allocation goes in one place). A third form, in which the caller provides the space and there is a wrapper function that uses either the local buffer or space from malloc(), is of course possible. >and longjmp()'s out of signal handlers (I consider this not worth much in most programs. Only in very restricted circumstances does this become valuable. Rarely, it *does* become very valuable; then the tradeoffs shift.) >with a lot less work than a malloc() based solution >It just leaves the nagging feeling that something necessary was omitted >from the language.... Quite possibly. See Dennis Ritchie's proposed variable-sized arrays for the things such an addition entails in a C-like language. >The argument that alloca isn't a requirement because it's little-used >(and it's little-used because its not required) doesn't help much >either. It is rather circular, but the circle exists now and as a result it is hard to break out of it. In my opinion, when breaking such a circle it is best to do so cleanly, and (also my opinion) alloca is *not* clean. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris