On Wed, 02 Jun 2010 15:34:32 -0400, Andrei Alexandrescu <seewebsiteforem...@erdani.org> wrote:

On 06/02/2010 02:27 PM, Steven Schveighoffer wrote:
On Wed, 02 Jun 2010 15:16:53 -0400, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:

On 06/02/2010 02:04 PM, Steven Schveighoffer wrote:
On Tue, 01 Jun 2010 21:59:20 -0400, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:

On 06/01/2010 08:53 PM, bearophile wrote:
Andrei Alexandrescu Wrote:
Walter and I agreed to let it go, but somehow forgot to
announce it.

Are stack-allocated (scoped) classes too gone?

De facto no, de jure yes.

I don't really understand this. Are they going to be gone or not?

In any case, can we at least keep them for unsafe D? Stack allocation is not easy to do via placement new, the compiler is much better suited for
it, and stack allocating classes can be a huge performance gain. Until
we get full escape analysis, scope classes are the only option.

There's no need for a language feature. I am implementing stack
allocation for classes in library code; I'm just undecided on where to
put it.

I think it belongs in druntime, since it's an allocation feature. How
easy is it to use?

The signature for non-class types is:

T* emplace(T, Args...)(void * address, Args args);

The function creates an object of type T at location address and initializes it with args. Returns a pointer to the just-created value. I needed this function for TightArray.

I haven't yet defined the signature for class types, but probably it would look like this:

T emplace(T, Args...)(void * address, Args args);

To obtain stack allocation, you may therefore write something like:

auto obj = emplace(alloca(_traits(classInstanceSize, T)), stuff);

Although it uses the obscure classInstanceSize, I think it's near the desired balance between terseness and making the programmer sweat for a dangerous achievement.

This makes it better than scope classes for one reason -- it's an expression instead of a declaration. That means I can use it to create a temporary.

But I have some qualms here -- when is the object's destructor called? I know it probably cannot be done any other way unless we had something like macros, but it's not easy for humans to parse this mess. Sure, it should be somewhat difficult for the developer to write, but what about the reader? I suppose there just isn't an easy way to do this.

Also, wouldn't it have to be something like this:

auto obj = emplace!T(alloca(_traits(classInstanceSize, T)), stuff);

And finally, is there any possible way to write an emplace that uses an allocator alias instead of the actual memory location? i.e.

T emplace2(T, alias alloc, Args...)(Args args)
{
   return emplace!(T, Args)(alloc(_traits(classInstanceSize, T)), args);
}

Anything to avoid the double-specification of T would be nice. This of course would be impossible to use with alloca without macros.

-Steve

Reply via email to