[comp.unix.questions] alloca problem?

hsu@santra.UUCP (Heikki Suonsivu) (11/03/88)

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? 

Inet: hsu@santra ................. Kuutamokatu 5 A 7 
Uucp: ...!mcvax!santra!hsu ....... 02210 Espoo .....
Fido: Heikki Suonsivu at 2:504/1 . FINLAND .........

leo@philmds.UUCP (Leo de Wit) (11/04/88)

In article <17026@santra.UUCP> hsu@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.

debra@alice.UUCP (Paul De Bra) (11/06/88)

In article <17026@santra.UUCP> hsu@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);
]
]	....
]}
]
This is not a problem of your Unix but of your program. Alloca does some
messing around with the stack. When you call it while you are pushing
arguments on the stack, you get in trouble. What I think is happening is
that name gets pushed on the stack, and then the alloca call moves the
stack pointer causing strcpy to go look for "name" in a different place.

The second example works because you first modify the stack and then
start pushing the arguments on the stack.
I am not saying that the first example won't work on any system (that has
alloca) but is is bad practice.

Paul.
-- 
------------------------------------------------------
|debra@research.att.com   | uunet!research!debra     |
------------------------------------------------------

hutch@net1.ucsd.edu (Jim Hutchison) (11/07/88)

If the code below would pass an ANSI-ized type checking, I can
see no problem.  On the other hand, it looks like a relatively
easy-to-make typing error (not typography, type).

Are integers different from pointers?  For instance, are integers
aligned?  Are pointers?  Are they the same size?  Do pointers require
extra processing due to some unusual characteristic in the
architecture?

If alloca() is not declared a (char *) in the code of the failing
example, it will/should generate a different bit of code to handle the
way its return value is placed on the stack.  Try adding an:
	extern char *alloca();

Hopefully this will make the difference you were wanting.

In article <17026@santra.UUCP> hsu@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);
>}

/*    Jim Hutchison   		UUCP:	{dcdwest,ucbvax}!cs!net1!hutch
		    		ARPA:	JHutchison@ucsd.edu
     These are my opinions, and now you have your perceptions of them. */