Re: glib: alloca brain damages



On Wed, 6 Jan 1999, Elliot Lee wrote:

> OK, #2 was a misunderstanding on my part, but #1 most definitely is a
> problem. RTH says any machine that does push/pop (m68k, x86) will have
> problems with that.
> 
> So, either the signature of g_new0_a needs to change, or we need to use
> the ({ ... }) construct (which is a gcc extension).

I don't have rigourous knowledge of alloca on various platforms, but my
gut feeling is that trusting any of its behaviour whatsoever is somewhat
dangerous. Furthermore, be very leary of trusting anything that "seems" 
to work in a limited set of examples, _especially_ Linux. (Linux is
extremely leniant about all sorts of stuff. This is very good for
developing portable software, as you can compile and run all sorts of
different code. However, this is horrible for _testing_ portable software,
as you never know quite what bits will break elsewhere.)

I'm aware that in many places alloca is emulated by a fairly standard
package that fakes it completely (using a reasonably portable technique
that cleans up defunct alloca blocks the next time alloca is invoked). 
Alternatively, if the compiler implements alloca directly (as does GCC),
then it may very well take care of the fiddly details for you, making it
appear to work properly even if invoked in a dubious manner. (GCC appears
to have logic along just these lines, though how it implements alloca will
surely differ on various systems. On some, it may provide the emulation
package automatically.) It's even possible (although I can't think of a
good mechanism at the moment) that the stack frame implementation on some
system could let it be used any which way, without problems -- but this
would say nothing about other systems.

A very brief review of gcc (as an example of a large program that uses
alloca extensively, not to mention implements it _and_ contains a copy of
the alloca emulation package) points to a few fairly obvious (to me at
least) things:

	Assume an alloca block ceases to exist outside its innermost
	enclosing scope. (That is, after all, the idea of alloca). Don't
	assume that only function scope counts. 

	Only use alloca in assignment statements. Simple expressions
	involving alloca are acceptable. ( x = alloc(6) + 3). Don't use
	it in more complex expressions or as a parameter.

	(These sorts of prohibitions are for the same basic reasons as the
	similar [and equally obscure] prohibitions on using the return
	value of setjmp. In both cases, the language is thin enough that
	implementation details are leaking through.)

	If the alloca emulation package is being used, using alloca(0)
	after leaving a scope that used a lot of alloca data is a good
	idea, as it forces the package to immediately clean up its
	garbage. I would reccomend that this is not safe if the emulation
	package is not being used, and I would also assume there is no
	good way of telling whether it is in use. 

Now, what does that leave us? It really doesn't look good for a macro, I'm
afraid. A gcc inline expression might very well work, but since gcc
already appears to be going out of its way to make alloca work, an inline
expression doesn't actually gain us anything. A fairly strange macro would
be needed to perform this safely, something vaguely like this: 

	#define assign_alloc_type_count(var,type,count)		\
		var = (type*)alloca(sizeof(type)*count),	\
		memset((void*)var, '\0', sizeof(type)*count),	\
		var

Though this hardly seems safe or even useful.

At this point, I'd really recommend that these macros get canned for the
moment, until and unless someone actually needs them. Providing them on
the grounds that "alloca is like malloc" seems to be an error.

-- 
Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126) 





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]