Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!usc!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: alloca() portability Keywords: portability, alloca Message-ID: <27537@mimsy.umd.edu> Date: 8 Nov 90 06:33:08 GMT References: <9032@ncar.ucar.edu> <499@taumet.com> <14377@smoke.brl.mil> <9122@ncar.ucar.edu> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 63 In article <9122@ncar.ucar.edu> steve@groucho.ucar.edu (Steve Emmerson) asks: >[Why not use alloca? Doug Gywn] admitted that systems on which [his] >alloca() couldn't work are few and far between. There are two reasons people use alloca() instead of malloc(). One is that alloca()'ed space goes away automatically. Doug Gwyn's implementation sometimes manages to achieve this, and even if not, it at least gets the code to run until all memory has been consumed. The other reason people use alloca() instead of malloc() is that it is more efficient. Since the `semi-portable' alloca() calls malloc(), the `it can be done' argument destroys the `it is more efficient' argument for these machines. The efficiency argument still holds on other machines. Unfortunately, on these machines, the source code foo(int n) { char *p = alloca(n); munge(p, n); /* munge needs n bytes of temporary space */ } (which appears likely to work) is quite likely to be compiled as foo(int n) { munge(alloca(n), n); } which is in fact fairly unlikely to work (it fails on, for instance, a VAX). To make it work, either we have to either produce suboptimal code for bar(int n) { char *p = jiggle(n); munge(p, n); } (which should in fact be compiled without the temporary) or else we have to gimmick the compiler to know about alloca(). (GCC 1.37.1 on a VAX produces the suboptimal code. The version without `p' uses r0 to hold n; the one with p uses r6, necessitating a push and pop during entry to and exit from bar().) The latter is medium-difficult but is in fact the only approach that is guaranteed always to work (provided, of course, that the compiler- gimmicking is done correctly). Since the ANSI standard does not *require* this, and since alloca() is little-used, it is not all that likely that most compiler vendors will do this. So we can say that, where alloca is more efficient than malloc, it is not safe (because optimising compilers may `move' calls to alloca so that they are made when the stack is not in its canonical format). Where alloca is not more efficient (because we have to use Doug Gywn's version or something equivalent), it is slightly more convenient. It is also at least slightly less portable. 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. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris