alloca

R

Richard Tobin

Moreover, there are systems where it is *not* implementable as such and
would be just an alias for malloc (now, who cares about a memory leak).

It could perfectly well be implemented as malloc() with free() on return
or longjmp().

-- Richard
 
D

Dik T. Winter

> Eric Sosman wrote: ....
>
> I don't exactly understand why you seem to assume that my conclusion is
> supposed to be based specifically on "studying implementations". I already
> explained that my conclusion is based solely on the fact of the existence
> of VLAs. I already commented the differences between VLAs and 'alloca'.
> Exhaustively, in my opinion.

There are differences that make VLAs more easy to implement on some systems.
Consider a system where the stack is used only to contain stuff used for
function entry (and is actually a stack, because the size used for entry
is the same for *every* function). Local variables are allocated in some
way from the heap. The function *knows* how much to deallocate when the
function exits, it is also able to find out how much to deallocate for
VLAs.
 
A

Andrey Tarasevich

Dik said:
There are differences that make VLAs more easy to implement on some systems.
Consider a system where the stack is used only to contain stuff used for
function entry (and is actually a stack, because the size used for entry
is the same for *every* function). Local variables are allocated in some
way from the heap. The function *knows* how much to deallocate when the
function exits, it is also able to find out how much to deallocate for
VLAs.

And the 'alloca' does not fit into that picture how exactly?
 
K

Keith Thompson

It could perfectly well be implemented as malloc() with free() on return
or longjmp().

Yes, it could, but it wouldn't be entirely trivial. Consider an
alloca() call in a loop. Consider the result of alloca() being
assigned to an object that goes out of scope before the end of the
function.

The code generated by the compiler would have to maintain a list (with
nodes allocated by malloc()) of pointers to alloca()-allocated blocks,
and traverse that list before leaving the function.

That's a lot of overhead for something that's supposed to be *simpler*
than malloc().
 
L

lawrence.jones

Chris Torek said:
Yes: the Standard says that setjmp is a macro, not a function.
Incidentally, this makes a number of implementations non-conforming
simply because they happen to use a function instead of a macro.

No, that's covered by 7.13p3:

It is unspecified whether setjmp is a macro or an identifier
declared with external linkage. If a macro definition is
suppressed in order to access an actual function, or a program
defines an external identifier with the name setjmp, the
behavior is undefined.

-Larry Jones

Let's pretend I already feel terrible about it, and that you
don't need to rub it in any more. -- Calvin
 
A

Andrey Tarasevich

user923005 said:
...
No, but I made my own version that does (it relies on non-portable
stuff).


void *alloca(size_t size)
{
void *p;
__try
{
p = _alloca(size);
}
__except(GetExceptionCode() == STATUS_STACK_OVERFLOW) {
int result = _resetstkoflw();
return NULL;
}
return p;
}
...

This implementation makes no sense. You can't wrap 'alloca' (or
'_alloca') calls into another function. The memory you allocated gets
automatically freed as you exit the wrapper. As a result, two
consecutive calls to your 'alloca' wrapper will most likely "allocate"
the same memory with obviously disastrous consequences.

If you want to produce your own version of 'alloca' by "wrapping" the
original, the only option you have is to wrap it into a macro.
 
R

Richard Tobin

Andrey Tarasevich said:
If you want to produce your own version of 'alloca' by "wrapping" the
original, the only option you have is to wrap it into a macro.

If you are sufficiently confident of your implementation (and this
code was certainly implementation-dependent), an inline function may
work.

-- Richard
 
R

Richard Tobin

It could perfectly well be implemented as malloc() with free() on return
or longjmp().
[/QUOTE]
The code generated by the compiler would have to maintain a list (with
nodes allocated by malloc()) of pointers to alloca()-allocated blocks,
and traverse that list before leaving the function.

Yes, though the list's pointers could be in the malloc()ed blocks
themselves.
That's a lot of overhead for something that's supposed to be *simpler*
than malloc().

Being cheap is certainly one of the aims of alloca(), but it's also
useful merely as an allocator of memory with dynamic extent.

And remember we're talking about implementing on systems where it's
for some reason impossible to allocate on the stack: that design
choice has its consequences, and it's not C's job to conceal them.

-- Richard
 
U

user923005

Oh, yes, I should have also asked for an implementation that actually
DOCUMENTS that alloca() returns NULL on failure, regardless of what
the code does.



Ok, alloca() usually relies on unportable stuff and hooks into the compiler.










Um, HOLD IT!  Doesn't, by definition, the storage allocated by
_alloca(), which I presume is Microsoft's implementation of alloca(),
get freed when the function calling _alloca() returns?  Doesn't
that mean that your alloca() returns a pointer to already-freed
storage?  That won't work very well.  alloca() doesn't like wrappers.

Also, are you guaranteed to get an exception if you overflow the
stack?  Ok, if you overflow it by a meg or less, probably.  If you
overflow it by the address difference between the current stack
pointer and &main, (say, a few gigabytes) maybe not.  You have
demonstrated a halfway reasonable way of stack checking that probably
works most of the time.

Quite right. This is an example where it would have to be implemented
as a function-like macro.
Enough reason not to try it right there.
 
M

Mark McIntyre

huw unsurprising that yet again, you totally ignore topicality.
There is no function called alloca() using Microsoft Visual C++,

And therein lies one of the problems of Jacob's stupid post.
 
D

Dik T. Winter

>
> It could perfectly well be implemented as malloc() with free() on return
> or longjmp().

Or goto. Using linked lists if alloca is used within a loop. See the
problems?
 
D

Dik T. Winter

>
> And the 'alloca' does not fit into that picture how exactly?

VLAs are only available immediately within a block. alloca is also
available in other places. Consider alloca within a loop. In that
case the compiler has to perform the task of maintaining dynamic linked
lists of the allocations in order to free the memory afterwareds.
 
R

Richard Tobin

Or goto. Using linked lists if alloca is used within a loop. See the
problems?

As far as I'm aware, alloca() returns memory whose life is that of the
calling function, so I don't see where goto comes into it. Goto never
crosses a boundary where the memory needs to be deallocated.

-- Richard
 
K

Kenneth Brody

Richard said:
As far as I'm aware, alloca() returns memory whose life is that of the
calling function, so I don't see where goto comes into it. Goto never
crosses a boundary where the memory needs to be deallocated.

What about something like:

void foo(void)
{
int a, b, c;
... code ...
while ( a > 0 )
{
int d, e, f;
char *pt = alloca(a);
... code ...
if ( d > 0 )
goto somewhere;
... code ...
}
... code ...
somewhere:
... code ...
while ( b > 0 )
{
double d, e, f;
char *pt = alloca(b);
... code ...
if ( d > 0 )
goto somewhere;
... code ...
}
... code ...
}

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
R

Richard Tobin

As far as I'm aware, alloca() returns memory whose life is that of the
calling function, so I don't see where goto comes into it. Goto never
crosses a boundary where the memory needs to be deallocated.
[/QUOTE]
What about something like:

What about it? I think we must be at cross-purposes. In my suggested
implementation, alloca() is just like malloc(), except that the memory
is freed when you return from the function or longjmp() from or back
across it. Jumping around in the function is irrelevant; the memory
doesn't get freed until you return.

I'm assuming that alloca() keeps its own list of allocated blocks
(perhaps chaining them together with pointers in the blocks
themselves) and doesn't rely on the values of variables to find
blocks to free - perhaps that is the confusion.

-- Richard
 
A

Andrey Tarasevich

Dik said:
VLAs are only available immediately within a block. alloca is also
available in other places.

In what "other places"? 'alloca' can only be used inside a function, which
immediately means that it is also "only available within a block".
Consider alloca within a loop.
And?

In that
case the compiler has to perform the task of maintaining dynamic linked
lists of the allocations in order to free the memory afterwareds.

That would only be only true if the compiler decided to translate every
individual 'alloca' call into something like an 'malloc' call that would later
require a matching 'free' call for every allocated block. While this can be
done, in reality it is absolutely unnecessary (and unwise) to implement 'alloca'
in that way.
 
D

Dik T. Winter

>
> In what "other places"? 'alloca' can only be used inside a function, which
> immediately means that it is also "only available within a block". ....
> That would only be only true if the compiler decided to translate every
> individual 'alloca' call into something like an 'malloc' call that would
> later require a matching 'free' call for every allocated block. While
> this can be done, in reality it is absolutely unnecessary (and unwise)
> to implement 'alloca' in that way.

What other way do you suggest in the context where I was writing in? (See
the quote at the top of the article, it was for a specific architecture.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top