alloca problem?

Leo de Wit leo at philmds.UUCP
Fri Nov 4 22:12:34 AEST 1988


In article <17026 at santra.UUCP> hsu at santra.UUCP (Heikki Suonsivu) writes:
|Why this fails,
|
|huu(name)
|	char *name;
|{
|	char *d;
|
|	d = strcpy(alloca(strlen(name) + 1), name);
|
|	....
|}
|
|but this works?
|
|huu(name)
|	char *name;
|{
|	char *d;
|
|	d = alloca(strlen(name) + 1);
|	strcpy(d, name);
|
|	....
|}
|
|I would like to have macro like
|#define strasave(s) strcpy(alloca(strlen(s) + 1), s);
|
|Problem appears when using microport 386 V.3 release 2.2. Is it a problem
|in me or alloca? 

Most probably a problem with alloca.
Some time ago, when discussions about alloca went high, one person
remarked that there are potentional problems in its use in parameters
passed to an other function. The compiler 'has to know of alloca()' to
be able to handle this in a clean manner. Consider:

   func(alloca(40),alloca(40),alloca(40));

The usual strategy (for stack based systems) is to evaluate and push
onto the stack each parameter expression in turn (in some
implementation dependent order). If this technique is followed in this
case also it will fail miserably, since the parameter values (pointers)
will be interspersed with the allocated chunks.

The problem of creating correct code for these uses of alloca() is not at
all trivial. For instance, consider (never mind what it means):

   func1(alloca(40),alloca(atoi(gets(alloca(30)))));

Copies of the parameters will have to be stashed away until all have
been calculated and can be put onto the stack (maybe the example is
still too trivial, but I think the intent is clear). Anyway, the
compiler has to know about alloca, or else use a unusual (inefficient)
parameter passing technique.

A quick hack for your macro (perhaps it works 8-):
Since the alloca is clearly done between pushing parameters, putting alloca
as the last parameter might work (assuming alloca() is called now before
pushing parameters):

#define strasave(s) rstrcpy(s, alloca(strlen(s) + 1))

where rstrcpy is defined by

char *rstrcpy(t,s) { return strcpy(s,t); }

The penalty is the overhead of an extra function call, but, as they say, you
can't win them all ...

                     Leo.



More information about the Comp.unix.wizards mailing list