Re: Regarding emplace, arrays, and helper functions

2013-08-30 Thread Andrej Mitrovic
On 8/30/13, Ali Çehreli acehr...@yahoo.com wrote:
 Now your program works with a single change:

  enum Size = paddedSize!C();

Excellent.

However will the compiler align all static arrays so their memory
begins at a proper offset?

Maybe a more appropriate question is: Is all stack data guaranteed to
be properly aligned, and on all platforms? For example:

enum Size = paddedSize!C;

ubyte[1] preBuffer;

ubyte[Size][2] buffer;

Is 'buffer' guaranteed to be aligned so its memory begins at a good
offset? There could be any number of bytes before 'buffer', such as
the preBuffer above it.

Tests show that they are indeed aligned, but I wonder if this is
something you can guarantee on all platforms?


Re: Regarding emplace, arrays, and helper functions

2013-08-30 Thread Namespace
I hate this magic library fix.. Why cannot we use 'scope' for 
this?
I know currently it is an unsafe feature that was also proposed 
for rejection, but it would look better, feel better, and the 
compiler could take the dirty work for us. And maybe better 
optimized.


Re: Regarding emplace, arrays, and helper functions

2013-08-30 Thread Andrej Mitrovic
On 8/30/13, Namespace rswhi...@googlemail.com wrote:
 I hate this magic library fix.. Why cannot we use 'scope' for
 this?
 I know currently it is an unsafe feature that was also proposed
 for rejection, but it would look better, feel better, and the
 compiler could take the dirty work for us. And maybe better
 optimized.

It would also avoid this nasty issue:
http://d.puremagic.com/issues/show_bug.cgi?id=10921


Re: Regarding emplace, arrays, and helper functions

2013-08-30 Thread Namespace

On Friday, 30 August 2013 at 14:45:40 UTC, Andrej Mitrovic wrote:

On 8/30/13, Namespace rswhi...@googlemail.com wrote:

I hate this magic library fix.. Why cannot we use 'scope' for
this?
I know currently it is an unsafe feature that was also proposed
for rejection, but it would look better, feel better, and the
compiler could take the dirty work for us. And maybe better
optimized.


It would also avoid this nasty issue:
http://d.puremagic.com/issues/show_bug.cgi?id=10921


Yes. :)


Re: Regarding emplace, arrays, and helper functions

2013-08-30 Thread Ali Çehreli

On 08/30/2013 07:02 AM, Andrej Mitrovic wrote:

 However will the compiler align all static arrays so their memory
 begins at a proper offset?

The compiler considers only the element type of the static array.

 Maybe a more appropriate question is: Is all stack data guaranteed to
 be properly aligned, and on all platforms?

I don't know the answer but I don't think it is specified even for C++.

 For example:

  enum Size = paddedSize!C;

  ubyte[1] preBuffer;

  ubyte[Size][2] buffer;

 Is 'buffer' guaranteed to be aligned so its memory begins at a good
 offset?

I don't think so because the elements are ubytes and they can be placed 
any odd address. Perhaps it works on the stack but the following 
align(1) struct demonstrates that your buffer can be at an odd address:


import std.stdio;

align(1)
struct S
{
ubyte[1] preBuffer;
ubyte[16][2] buffer;
}

void main()
{
writeln(S.preBuffer.offsetof);// prints 0
writeln(S.buffer.offsetof);   // prints 1
}

Ali



Re: Regarding emplace, arrays, and helper functions

2013-08-29 Thread bearophile

A little related:
http://d.puremagic.com/issues/show_bug.cgi?id=8873

Bye,
bearophile


Re: Regarding emplace, arrays, and helper functions

2013-08-29 Thread Ali Çehreli

On 08/29/2013 05:20 AM, Andrej Mitrovic wrote:

 The emplace docs state that the chunk where to store the class object
 instance needs to be aligned to the class type alignment. But it
 doesn't say much on how to get this alignment from a class (we could
 add a note about using the classInstanceAlignment template), or even
 how to use it to create e.g. an array of class objects (not an array
 of references).

 Here's how one can run into a problem:

 -
 import std.conv;

 class C
 {
  this(ubyte b) { _b = b; }
  ubyte _b;
 }

 void main()
 {
  // 9 bytes (x32), it's not going to align itself properly
  enum Size = __traits(classInstanceSize, C);

  ubyte[Size][2] buffer;

  // off-topic: cast needed - yet another emplace bug
  auto obj1 = emplace!C(buffer[0], cast(ubyte)20);
  assert(obj1._b == 20);

  auto obj2 = emplace!C(buffer[1], cast(ubyte)20);  // Boom!
  assert(obj2._b == 20);
 }
 -

 On the second emplace call, an exception is thrown:

 -
 std.conv.ConvException@std\conv.d(3832): emplace: Misaligned memory
 block (0x18FD41): it must be 4-byte aligned for type C
 -

 So one has to figure out how to do alignment properly, but there's no
 real documentation on how to do it.

I had experimented with this in a chapter (not in English yet):

  http://ddili.org/ders/d/bellek_yonetimi.html

Here are two functions that I have just translated from that page (I see 
that alignedAddress should better be alignUp):


T * alignedAddress(T)(T * candidateAddress)
out (result)
{
assert((cast(size_t)result % T.alignof) == 0);
}
body
{
return cast(T*)((cast(size_t)candidateAddress + T.alignof - 1)
/ T.alignof * T.alignof);
}

size_t paddedSize(T)()
{
static if (is (T == class)) {
size_t size = __traits(classInstanceSize, T);

} else {
size_t size = T.sizeof;
}

return cast(size_t)alignedAddress(cast(T*)size);
}

Now your program works with a single change:

enum Size = paddedSize!C();

Ali