Re: Regarding emplace, arrays, and helper functions
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
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
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
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
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
A little related: http://d.puremagic.com/issues/show_bug.cgi?id=8873 Bye, bearophile
Re: Regarding emplace, arrays, and helper functions
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