Summary: emplace() for classes accepts larger chunk but fails
                    in array assignment
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos

--- Comment #0 from Ali Cehreli <> 2011-06-24 00:20:13 PDT ---
This is tested with dmd 2.053 release version.

In the class version of emplace(), the following enforce indicates that it is
legal to have a chunk larger than the instance size:

    enforce(chunk.length >= __traits(classInstanceSize, T),
           new ConvException("emplace: chunk size too small"));

Unfortunately, the following array assignment fails when that's the case:

    // Initialize the object in its pre-ctor state
    (cast(byte[]) chunk)[] = typeid(T).init[];

Here is a program that reproduces the issue:

import std.conv;

class C
    int i;

size_t alignedSize(T)()
    return (__traits(classInstanceSize, T) + T.alignof - 1)
        / T.alignof * T.alignof;

void main()
    enum roomPerObject = alignedSize!C();

    ubyte[roomPerObject] buffer;
    void[] placeForObject = (buffer.ptr)[0..roomPerObject];


The last line throws at runtime:

object.Exception@src/rt/arraycat.d(31): lengths don't match for array copy

A proposed fix would be to assign only to the first part of the chunk:

    (cast(byte[]) chunk)[0..__traits(classInstanceSize, T)] = typeid(T).init[];

(Note the range on the left hand side of the assignment.)

That gets rid of the problem but I am not sure about what to do with the
potentially-non-zero remaining bytes of the chunk. The caller may assume that
they will be cleared by emplace().

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to