This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

In C6000 compiler, what is the equivalent function to replace "alloca" from other compilers

Hi TI,

I am new to C6000 compiler.

I am trying to port some code from Windows platform to C64x+ DSP platform.

The C6000 compiler gives this error : error #20: identifier "alloca" is undefined

In my source file, there is this below definition :

#define cvStackAlloc(size) cvAlignPtr( alloca((size) + CV_MALLOC_ALIGN), CV_MALLOC_ALIGN )

What is the equivalent "alloca" function in C6000 compiler  to replace the above "alloca" ?

Thanks,

Mr Tan

  • No TI compiler, including the C6000 compiler, supports alloca.  Nor is there any equivalent.  Note alloca is not part of the ANSI standard for C, but is an extension.

    Thanks and regards,

    -George

  • Alloca is an abomination, but if you have existing code that requires it, you can use my nearly-portable C implementation of alloca.  You can find various adaptations of it as used in dozens of projects by searching the Web for "alloca.c" and "D A Gwyn".  Or you can try my latest edition; hopefully this post will make it visible:

    /*
    	alloca - allocate automatically reclaimed memory
    		(Mostly) portable public-domain implementation
    
    	created:	1986		D A Gwyn
    	last edit:	2012-06-01	D A Gwyn	reconstructed & tweaked
    
    	This implementation of the PWB library alloca() function,
    	which is used to allocate space off the run-time stack so
    	that it is automatically reclaimed upon procedure exit, 
    	was inspired by discussions with J. Q. Johnson of Cornell.
    
    	It should work under any C implementation that uses an
    	actual procedure stack (as opposed to a linked list of
    	frames).  There are some preprocessor constants that can
    	be predefined when compiling for your specific system, for
    	improved efficiency; however, the defaults should be okay.
    
    	The general concept of this implementation is to keep
    	track of all alloca()-allocated blocks, and reclaim any
    	that are found to be deeper in the stack than the current
    	invocation.  This heuristic does not reclaim storage as
    	soon as it becomes invalid, but it will do so eventually.
    
    	As a special case, alloca(0) reclaims storage without
    	allocating any.  It is a good idea to use alloca(0) in
    	your main control loop, etc. to force garbage collection.
    
    	The original behavior of alloca() when it was unable to
    	allocate storage was to just run amok or abort the program.
    	I much prefer that it return NULL, similar to the standard
    	C library allocation functions; to obtain this behavior,
    	you must predefine RETURN_NULL_ON_FAILURE when compiling.
    
    	Predefine STACK_DIRECTION if you know the direction of stack
    	growth for your system; otherwise it will be automatically
    	deduced at run-time.
    		STACK_DIRECTION > 0 => grows toward higher addresses
    		STACK_DIRECTION < 0 => grows toward lower addresses
    		STACK_DIRECTION = 0 => direction of growth unknown
    
    	If you know the byte alignment enforced by malloc() for
    	the chunks that it allocates, you should predefine
    	ALIGN_SIZE as that integer constant.
    
    	If you need to port this implementation to a platform where
    	data objects in stack frames do not have a byte addresses
    	that directly reflect the frame nesting sequence, then you
    	must predefine LINEARIZE as the name of a helper function
    	that converts the address of a local "auto" object to some
    	pointer value that does have that property.  Note that
    	there can be C implementations on segmented architectures
    	where pointer comparison (other than for equality) between
    	different segments is not meaningful; in that case, there
    	is no simple solution, other than to avoid using alloca().
    
    	This code has not been verified to operate properly in a
    	multithreaded environment.
    
    	Author's note:  alloca() was originally implemented by
    	simply adjusting the run-time stack pointer and returning
    	a pointer to the new portion of the stack.  This was faster
    	and somewhat more convenient than using malloc()/free(), and
    	many programmers made heavy use of alloca().  Unfortunately,
    	it is hard to implement alloca() correctly on some platforms,
    	for reasons I won't explain here (but you might find it
    	instructive to puzzle out ways in which there could be a
    	problem).  Probably the worst issue with alloca() is that it
    	was assumed to always successfully allocate more storage,
    	and it did not report when it was unable to.  The original
    	release of this implementation was meant as a transitional
    	measure only; you should not be writing new code that relies
    	on alloca(), and you should refit old code to use malloc()/
    	free() instead as you get the chance.  Unfortunately, the
    	very existence of this "temporary" implementation encouraged
    	many C programmers to continue to use alloca() in new code!
    	For example, it was included in the GNU Emacs distribution.
    	A search of the World Wide Web shows its use, usually with
    	a few slight environmental adaptations, in dozens of projects.
    
    	I have reviewed many of the adaptations, and have tweaked
    	my master copy of the source code to incorporate the more
    	worthwhile ones.  However, I did not pick up modifications
    	that J. Otto Tennant had made to provide alloca() on Cray
    	platforms that use linked activation-record segments instead
    	of contiguous stack frames; that is because it incorporated
    	a large amount of highly platform-specific code.  I did adopt
    	part of the Cray modifications, in the form of LINEARIZE().
    
    	The 1999 revision of the C standard introduced support for
    	variable-length arrays (VLAs), which could be used much the
    	same as alloca() had been used.  However, compilers were slow
    	to implement the VLA facility (and some other C99 features).
    	Therefore, this implementation may still be of use.
    */
    
    #if	! (defined(lint) || defined(_lint_) || defined(LINT))
    static char	SCCSid[] = "@(#)alloca.c\t1.3"; /* for the "what" utility */
    #endif
    
    #ifndef	alloca	/* else probably defined as _builtin_alloca */
    
    #ifdef	__STDC__
    
    #include	<stdlib.h>
    
    typedef void *	pointer;		/* generic pointer type (Std C) */
    
    #else	/* !defined(__STDC__) */	/* assume pre-ANSI; no prototypes */
    
    extern void		abort( /* void */ );
    extern void		free( /* pointer */ );
    extern pointer	malloc( /* size_t */ );
    
    typedef char *	pointer;		/* generic pointer type (K&R C) */
    
    #define	NULL	0			/* null pointer constant */
    
    #endif	/* !defined(__STDC__) */
    
    /*
    	LINEARIZE is the name of either a function-like macro or an
    	actual function (to which LINEARIZE has been predefined).
    	It must return pointer values with the property that they
    	can be directly compared for inequality resulting in an
    	ordering that consistently (in one direction or the other)
    	reflects the actual stack hierarchy for the local "auto"
    	variables whose arguments are passed to LINEARIZE().
    
    	On some platforms, such a mapping may be infeasible to
    	implement.  In that case, you should avoid using alloca().
    */
    
    #ifdef	LINEARIZE			/* name of a helper function */
    extern char *	LINEARIZE( /* char* */ );
    #else	/* don't need help: cross-frame comparison works */
    #define	LINEARIZE( p )	(p)
    #define
    #endif
    
    /*
    	Predefine STACK_DIRECTION if you know the direction of stack
    	growth for your system; otherwise it will be automatically
    	deduced at run-time.
    
    	STACK_DIRECTION > 0 => grows toward higher addresses
    	STACK_DIRECTION < 0 => grows toward lower addresses
    	STACK_DIRECTION = 0 => direction of growth unknown
    */
    
    #ifndef	STACK_DIRECTION
    #define	STACK_DIRECTION	0		/* initially unknown */
    #endif
    
    #if	STACK_DIRECTION != 0
    
    #define	STK_DIR	STACK_DIRECTION	/* known at compile-time */
    
    #else	/* STACK_DIRECTION == 0; need run-time probe */
    
    static int	stack_dir = 0;			/* 1 or -1 once known */
    #define	STK_DIR	stack_dir
    
    static void
    find_stack_direction( /* void */ )
    	{
    	static char *	addr = (char *)NULL;	/* address for
    								   first "dummy",
    								   once known */
    	auto char		dummy;		/* to get stack address */
    
    	if ( addr == NULL )
    		{					/* initial entry */
          	addr = LINEARIZE( &dummy );
    
    		find_stack_direction();		/* recurse once */
    		}
    	else						/* second entry */
    		if ( LINEARIZE( &dummy ) > addr )	/* crucial test */
    			stack_dir = 1;		/* stack grew upward */
    		else
    			stack_dir = -1;		/* stack grew downward */
    	}
    
    #endif	/* STACK_DIRECTION == 0 */
    
    /*
    	An "alloca header" is used to:
    	(a) chain together all alloca()ed blocks;
    	(b) keep track of stack depth.
    
    	It is very important that sizeof(header) agree with malloc()
    	alignment chunk size.  The following default should work okay.
    */
    
    #ifndef	ALIGN_SIZE
    #define	ALIGN_SIZE	sizeof(double)
    #endif
    
    typedef union hdr
    	{
    	char		align[ALIGN_SIZE];	/* to force sizeof(header) */
    	struct
    		{
    		union hdr *	next;			/* for chaining headers */
    		char *	deep;			/* for stack depth measure */
    		}	h;
    	}	header;
    
    /*
    	alloca( size ) returns a pointer to at least "size" bytes of
    	storage which will be automatically reclaimed upon exit from
    	the procedure that called alloca().  Originally, this space
    	was supposed to be taken from the current stack frame of the
    	caller, but that method cannot be made to work for some
    	implementations of C, for example under Gould's UTX/32.
    */
    
    pointer
    alloca( size )				/* returns pointer to storage */
    	unsigned		size;			/* # bytes to allocate */
    	{
    	static header *	last = NULL;	/* -> last alloca header */
    	auto char		probe;		/* probes stack depth: */
    	register char *	depth = &probe;
    
    #if	STACK_DIRECTION == 0
    	if ( STK_DIR == 0 )			/* unknown growth direction */
    		find_stack_direction();
    #endif
    
    	/* Reclaim garbage, defined as all alloca()ed storage that
    	   was allocated from deeper in the stack than currently. */
    
    		{
    		register header *	hp;		/* traverses linked list */
    
    		for ( hp = last; hp != NULL; )
    			if ( STK_DIR > 0 && hp->h.deep > depth
    			  || STK_DIR < 0 && hp->h.deep < depth
    			   )	{
    				register header *	np = hp->h.next;
    
    				free( (pointer)hp );	/* collect garbage */
    
    				hp = np;		/* -> next header */
    				}
    			else
    				break;		/* rest are not deeper */
    
    		last = hp;				/* -> last valid storage */
    		}
    
    	if ( size == 0 )
    		return (pointer)NULL;		/* no allocation required */
    
    	/* Allocate combined header + user data storage. */
    
    		{
    		register pointer	newa = malloc( sizeof(header) + size );
    							/* address of header */
    
    		if ( newa == NULL )
    #ifdef	RETURN_NULL_ON_FAILURE
    			return (pointer)NULL;
    #else
    			abort();			/* abort() is traditional */
    #endif
    
    		((header *)newa)->h.next = last;
    		((header *)newa)->h.deep = depth;
    
    		last = (header *)newa;
    
    		/* User storage begins just after header. */
    
    		return (pointer)((char *)newa + sizeof(header));
    		}
    	}
    
    #endif /* !defined(alloca) */
    

  • The above inspired me to produce a new "master" version of the C implementation of alloca (attached).  It now has historical notes etc. in the front comments.

    /*
    	alloca - allocate automatically reclaimed memory
    
    	(mostly) portable public-domain alternative to platform-
    	dependent versions.
    
    	created:	1986-01-26	gwyn@arl.army.mil
    	last edit:	2012-06-02	D A Gwyn
    	SCCS id:	@(#)alloca.c	1.4
    
    	Specification:
    
    		extern void * alloca( size_t size );
    
    	alloca() allocates a contiguous region of storage having at
    	least the requested number of bytes (size), properly aligned for
    	containing any supported C data type.  It returns a pointer to
    	the start of the allocated region.  The allocation will be
    	automatically freed after the currently executing function
    	terminates.  Behavior is undefined when the requested amount of
    	storage cannot be allocated.  (In a perfect world, NULL would be
    	returned in that case; however, some existing implementations do
    	not guarantee that.)  Behavior is also undefined if alloca() is
    	used in a function argument (due to existing implementations).
    
    	alloca() might not operate properly in a multi-threaded
    	application (including from asynchronous signal handlers).
    
    	General information:
    
    	This reimplementation of the PWB/Unix library alloca() function,
    	which was used to allocate space off the run-time stack so that
    	it would be automatically reclaimed upon procedure exit, was
    	inspired by discussions with J. Q. Johnson of Cornell.  Later,
    	changes were made to accommodate a wider range of environments.
    
    	It should work for any C run-time model that uses a contiguous
    	stack (as opposed to a linked list of frames).  There are some
    	preprocessor macros that can be predefined when compiling for
    	your specific system (see below); however, the defaults should
    	be okay in most cases.
    
    	The general concept of this implementation is to keep track of
    	all alloca()-allocated blocks, and reclaim any that are found to
    	be deeper in the stack than the current invocation.  This
    	heuristic does not reclaim storage as soon as it becomes
    	invalid, but it will do so eventually.
    
    	Note that alloca(0) reclaims storage without allocating any.  It
    	may be a good idea to use alloca(0) in your main control loop,
    	etc. to force garbage collection.
    
    	Configuration:
    
    	The original behavior of alloca() when it was unable to allocate
    	storage was to just run amok and/or abort the program. It would
    	be better for it to return NULL, similar to the standard C
    	library allocation functions.  This implementation by default
    	returns NULL when storage is not allocated; if you predefine
    	ALLOCA_ABORT when compiling, it will call abort() when storage
    	cannot be allocated.
    
    	As of this writing, the vast majority of C implementations
    	maintain run-time procedure call frames as a contiguous array
    	commonly called "the stack".  This version of alloca() was
    	designed to exploit that model.  Predefine ALLOCA_STACK_DIRECTION
    	if you know the direction of stack growth for your system* when a
    	function is invoked; otherwise it will be automatically deduced
    	at run time.
    		*Please do not insert specific platform definitions into
    		 this source file.
    
    	ALLOCA_STACK_DIRECTION > 0 => grows toward higher addresses
    	ALLOCA_STACK_DIRECTION < 0 => grows toward lower addresses
    	ALLOCA_STACK_DIRECTION = 0 => direction of growth unknown
    
    	If you need to port this implementation to a platform where data
    	objects in stack frames do not have byte addresses that directly
    	reflect the frame nesting sequence (for example, procedure call
    	frames may be dynamically allocated from the heap, with links to
    	provide the stack-like behavior), then you must predefine
    	ALLOCA_LINEARIZE as the name of a helper function* that converts
    	the address of a local "auto" object of type int to some
    	alternative int-pointer value that does have that property.
    	This may not always be possible without changing the C run-time
    	system to add stack depth information to the call frame.
    		*Please do not insert platform-dependent code into this
    		 source file.  Instead, provide the helper function,
    		 with external linkage, in a separate file.
    
    	If you want to replace calls to malloc() and/or free() with some
    	other function(s) having the same interface, for example PWB's
    	xmalloc(), predefine ALLOCA_MALLOC and/or ALLOCA_FREE to the
    	desired name(s).
    
    	If you know the storage alignment enforced by malloc() for the
    	chunks that it allocates, you should predefine ALLOCA_CHUNK_SIZE
    	as that number of bytes.  Otherwise a kludge will be used that
    	nearly always works, but is not guaranteed.
    
    	Historical notes:
    
    	alloca() was originally implemented by simply adjusting the
    	run-time stack pointer and returning a pointer to the new
    	portion of the stack.  This was faster and somewhat more
    	convenient than using malloc()/free(), so many programmers
    	made heavy use of alloca().  (However, it had to be avoided in
    	function arguments, because it disrupted the function linkage.)
    	Unfortunately, it is hard to implement alloca() on some more
    	recent platforms, as indicated above.  Probably the worst issue
    	with alloca() is that programmers usually assumed that it would
    	always successfully allocate more storage, and it did not report
    	when it was unable to perform the allocation.  That could result
    	in a trap later on when the program tries to access an
    	unavailable storage location.  (C itself has a similar problem
    	when there is not enough stack space remaining to complete
    	instantiating a function call.)
    
    	As an example, here is the entire PDP-11 Unix implementation:
    
    	/	ptr = alloca(nbytes);
    	/ like malloc, but automatic free upon return from calling
    	/ function
    		.globl	_alloca
    	_alloca:
    		mov	(sp)+,r1	/ return
    		mov	(sp),r0		/ count
    		inc	r0
    		bic	$1,r0		/ round up
    		/ XXX -- should plant SIGSEGV catcher, probe @(r0-sp),
    		/ return NULL on trap
    		sub	r0,sp		/ take core
    		mov	sp,r0
    		tst	(r0)+		/ returned pointer value;
    		/ may generate a memory fault if there isn't enough
    		/ core; otherwise it expands the allocation so there
    		/ will be no page fault later upon access
    		jmp	(r1)
    
    	Because of these problems, alloca() was not included in the C
    	standard, and for improved program portability the standard
    	malloc()/free() facility was recommended as a replacement.  The
    	original release to the public domain of this C implementation
    	of alloca() was meant to aid this transition, and new code
    	should not have been written to rely on alloca() in the first
    	place.  Unfortunately, the very existence of this "temporary"
    	implementation seems to have encouraged many C programmers to
    	continue to use alloca() in new code!  For example, a modified
    	version of this implementation was included in the GNU Emacs
    	distribution.  A search of the World Wide Web shows that it has
    	been used, often with slight environmental adaptations, in
    	dozens of projects.
    
    	The author has reviewed many of the adaptations, and has tweaked
    	his master copy of the source code to incorporate the more
    	worthwhile ones.  However, kludges to accommodate *specific*
    	platforms have not been included.  Any that are still deemed
    	necessary could be reinserted into this version.
    
    	The 1999 revision of the C standard introduced support for
    	variable-length arrays (VLAs), which could be used much the same
    	way as alloca().  However, compiler providers were slow to
    	implement the VLA facility (and several other C99 features).
    	Therefore this alloca() implementation may still be of some use.
    */
    
    #ifndef	alloca	/* else probably defined as __builtin_alloca (GCC) */
    
    #ifdef	__STDC__
    
    #include	<stddef.h>		/* NULL, offsetof, size_t */
    #include	<stdlib.h>		/* abort, free, malloc */
    
    #if	__STDC_VERSION__ >= 199901
    #include	<stdint.h>		/* uintmax_t */
    #else	/* C90 */
    typedef unsigned long	uintmax_t;	/* may not have long long */
    #endif
    
    typedef void *		pointer;	/* generic pointer type */
    typedef long double	long_double;
    
    #else	/* !defined(__STDC__) */	/* assume pre-ANSI ("K&R") */
    
    typedef unsigned	size_t;		/* may not have <stdlib.h> */
    typedef unsigned long	uintmax_t;	/* may not have <stdint.h> */
    typedef char *		pointer;	/* generic pointer type */
    typedef double		long_double;	/* may not have long double */
    
    extern void	abort( /* void */ );
    extern void	free( /* pointer */ );
    extern pointer	malloc( /* size_t */ );
    
    #ifndef	NULL	/* (shouldn't need to predefine, but just in case...) */
    #define	NULL	0			/* null pointer constant */
    #endif
    
    #define	offsetof( t, m )	((size_t)&(((t)*)0)->m)
    					/* works on many compilers */
    
    #endif	/* !defined(__STDC__) */
    
    #ifndef	ALLOCA_MALLOC
    #define	ALLOCA_MALLOC	malloc
    #endif
    
    #ifndef	ALLOCA_FREE
    #define	ALLOCA_FREE	free
    #endif
    
    /*
    	ALLOCA_LINEARIZE is the name of either a function-like macro
    	(defined below) or an external function (to which
    	ALLOCA_LINEARIZE has been predefined).  It must return
    	replacement int-pointer values that can be directly compared for
    	inequality, resulting in an ordering that consistently (in one
    	direction or the other) reflects the actual stack hierarchy for
    	the local "auto" int variables whose addresses are passed to
    	ALLOCA_LINEARIZE().  This may not always be possible without
    	changing the C run-time system to add stack depth information to
    	the call frame.
    */
    
    #ifdef	ALLOCA_LINEARIZE		/* name of a helper function */
    extern int *	ALLOCA_LINEARIZE( /* int * */ );
    #else	/* don't need help: cross-frame ordering comparison works */
    #define	ALLOCA_LINEARIZE( p )	(p)
    #endif
    
    /*
    	Predefine ALLOCA_STACK_DIRECTION if you know the direction of stack
    	growth for your system; otherwise it will be automatically
    	deduced at run time.
    
    	ALLOCA_STACK_DIRECTION > 0 => grows toward higher addresses
    	ALLOCA_STACK_DIRECTION < 0 => grows toward lower addresses
    	ALLOCA_STACK_DIRECTION = 0 => direction of growth unknown
    */
    
    #ifndef	ALLOCA_STACK_DIRECTION
    #define	ALLOCA_STACK_DIRECTION	0	/* initially unknown */
    #endif
    
    #if	ALLOCA_STACK_DIRECTION == 0
    
    /* run-time code to determine stack direction: */
    
    static int	stack_dir = 0;		/* 1 or -1 once known */
    
    static void
    find_stack_direction( /* void */ )
    	{
    	static int *	addr = (int *)NULL;	/* address for first
    						   "dummy", once known */
    	auto int	dummy;		/* to get stack address */
    
    	if ( addr == NULL )
    		{			/* initial entry */
    		addr = ALLOCA_LINEARIZE( &dummy );
    
    		find_stack_direction();	/* recurse once */
    		}
    	else				/* second entry */
    		if ( ALLOCA_LINEARIZE( &dummy ) > addr )
    			stack_dir = 1;	/* stack grew upward */
    		else
    			stack_dir = -1;	/* stack grew downward */
    	}
    
    #endif	/* ALLOCA_STACK_DIRECTION == 0 */
    
    /*
    	An "alloca header" is used to:
    	(a) chain together all alloca()ed blocks;
    	(b) keep track of stack depth.
    
    	It is very important that sizeof(header) be a multiple of the
    	widest required alignment (in bytes) for any data type.  This
    	can be predefined as ALLOCA_CHUNK_SIZE if you are sure of it;
    	otherwise, the following default computation should work okay.
    */
    
    #ifndef	ALLOCA_CHUNK_SIZE
    
    struct al_st
    	{
    	char		al_cm;
    	union	{		/* suggested by Hallvard B. Furuseth */
    		uintmax_t	al__m;
    		long_double	al__d;
    		pointer		al__p;
    		void (*		al__f)( /* void */ );
    		}	al_um;
    	};
    
    #define	ALLOCA_CHUNK_SIZE	offsetof( struct al_st, al_um )
    
    #endif	/* !defined(ALLOCA_CHUNK_SIZE) */
    
    typedef union hdr
    	{
    	char	align[ALLOCA_CHUNK_SIZE];	/* force padding */
    	struct
    		{
    		union hdr *	next;	/* for chaining headers */
    		int *		deep;	/* for stack depth measure */
    		}	h;
    	}	header;
    
    /*
    	alloca( size ) returns a pointer to at least "size" bytes of
    	storage which will be automatically reclaimed upon exit from
    	the procedure that called alloca().  Originally, this space
    	was supposed to be taken from the current stack frame of the
    	caller, but that method cannot be made to work for some
    	implementations of C, for example under Gould's UTX/32.
    */
    
    static header *	last_alloca_header = NULL;
    					/* -> last alloca header */
    
    pointer
    alloca( size )				/* returns pointer to storage */
    	size_t	size;			/* # bytes to allocate */
    	{
    	auto int	probe;		/* probes stack depth: */
    	register int *	depth = ALLOCA_LINEARIZE( &probe );
    
    #if	ALLOCA_STACK_DIRECTION == 0	/* growth direction not known */
    	if ( stack_dir == 0 )		/* true only for first entry */
    		find_stack_direction();
    #endif
    
    	/* Reclaim garbage, defined as all alloca()ed storage that
    	   was allocated from deeper in the stack than currently. */
    
    	{
    	register header *	hp;	/* traverses linked list */
    
    	for ( hp = last_alloca_header; hp != NULL; )
    		if (
    #if	ALLOCA_STACK_DIRECTION == 0	/* direction wasn't known */
    		     stack_dir > 0 && hp->h.deep > depth
    		  || stack_dir < 0 && hp->h.deep < depth
    #elif	ALLOCA_STACK_DIRECTION > 0
    		     hp->h.deep > depth	/* deeper is obsolete */
    #else	/* ALLOCA_STACK_DIRECTION < 0 */
    		     hp->h.deep < depth	/* deeper is obsolete */
    #endif
    		   )	{
    			register header *	np = hp->h.next;
    
    			/* Recycle trash. */
    
    			ALLOCA_FREE( (pointer)hp );
    
    			hp = np;	/* -> next header */
    			}
    		else
    			break;		/* the rest are not deeper */
    
    	last_alloca_header = hp;	/* -> last valid storage */
    	}
    
    	if ( size == 0 )
    		return (pointer)NULL;	/* no allocation required */
    
    	/* Allocate combined header + user data storage. */
    
    	{
    	register pointer	newa =	/* address of header: */
    			ALLOCA_MALLOC( sizeof(header) + size );
    					
    
    	if ( newa == NULL )
    #ifdef	ALLOCA_ABORT
    		abort();		/* traditional behavior */
    #else
    		return (pointer)NULL;
    #endif
    
    	((header *)newa)->h.next = last_alloca_header;
    	((header *)newa)->h.deep = depth;
    
    	last_alloca_header = (header *)newa;
    
    	/* User storage begins just after header. */
    
    	return (pointer)((unsigned char *)newa + sizeof(header));
    	}
    
    	}
    
    #endif /* !defined(alloca) */