Variable-length stack allocated arrays
dsimcha
dsimcha at yahoo.com
Mon Jan 11 18:46:37 PST 2010
== Quote from Chad J (chadjoan at __spam.is.bad__gmail.com)'s article
> http://d.puremagic.com/issues/show_bug.cgi?id=3696
> I'm realizing now that returning an object allocated on this stack is a
> tricky task unless there is help from the caller. The lifetime of the
> object has to be determined somehow. The Tango convention makes it
> fairly explicit that the parent's scope will be the beginning and the
> end for the memory. If it needs to live longer then the caller just
> passes a buffer that isn't stack/scoped memory. Only the caller really
> knows how long the memory needs to hang around. hmmmmm.
The optional buffer idiom is great for stuff that's returned from a function. I
use it all the time. On the other hand, for temporary buffers that are used
internally, whose mere existence is an implementation detail, having the caller
maintain and pass in a buffer is a horrible violation of encapsulation and good
API design, even by the standards of performance-oriented APIs. Even if you know
it's never going to change, it's still annoying for the caller to even have to
think about these kinds of details.
> Still that SuperStack thing would be useful. It's like alloca but
> better (look ma, no cast) and slightly more general (ex: it can be freed
> in parent's scope, if you are willing to play it risky).
Yeah, for about the past year I've been playing around with TempAlloc, wich was
basically me taking Andrei's SuperStack idea when it was first proposed and
running with it because I needed it sooner rather than later. It's basically
encapsulated in dstats.alloc
(http://svn.dsource.org/projects/dstats/docs/alloc.html).
Its one **huge** bug that I've been trying to fix is that it's not scanned by the
GC because scanning the whole stack would be too inefficient and I can't think of
a way to do it more efficiently. However, it's still useful in cases where either
you're just rearranging data and there's already a copy somewhere that is scanned
by the GC (sorting for non-parametric statistical calculations is my killer use)
or your data is pure value types like floats. It's got the following advantages
over alloca:
1. Can't overflow unless you're completely out of address space. As a last
resort, it allocates another chunk of memory from the heap.
2. Nicer syntax. For example, to allocate an array of 1,000 uints:
auto foo = newStack!uint(1_000);
3. Since lifetimes are not bound to any function scope unless you want them to
be, you can implement complex abstract data structures (I've got hash tables, hash
sets and AVL trees so far) on this stack. This is useful when you need to build a
lookup table as part of some algorithm.
More information about the Digitalmars-d
mailing list