insertInPlace differences between compilers

John McFarlane via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Nov 12 11:25:48 PST 2014


On Wednesday, 12 November 2014 at 19:15:24 UTC, John McFarlane 
wrote:
> On Wednesday, 12 November 2014 at 00:31:31 UTC, Jesse Phillips 
> wrote:
>> On Tuesday, 11 November 2014 at 20:53:51 UTC, John McFarlane 
>> wrote:
>>> I'm trying to write a struct template that uses 
>>> `insertInPlace`. However, it doesn't work with certain 
>>> template type / compiler combinations. Consider the following:
>>>
>>>   import std.range;
>>>   struct S { const int c; }
>>>   S[] a;
>>>   insertInPlace(a, 0, S());
>>>
>>> With DMD64 D Compiler v2.066.1, I get the following error:
>>> /usr/include/dmd/phobos/std/array.d(1013): Error: cannot 
>>> modify struct dest[i] S with immutable members
>>> /usr/include/dmd/phobos/std/array.d(1079): Error: template 
>>> instance std.array.copyBackwards!(S) error instantiating
>>> ./d/my_source_file.d(12345):        instantiated from here: 
>>> insertInPlace!(S, S)
>>
>> I believe DMD is correct here and here is why:
>>
>> While the function is called "insert" the operation is 
>> actually an assignment. DMD initializes all arrays elements to 
>> the default value so your array position 0 actually contains 
>> an S already. This means the operation is equivalent to
>>
>>    auto b = S();
>>    b = S();
>>
>> Since S is a value type you're actually making a modification 
>> 'c' as stored in 'b'. The compiler is unable to prove that 
>> there is no other reference to that same memory location 
>> (though in this case the variable is on the stack and the 
>> modification is local so such knowledge may be possible).
>>
> That makes sense. In the case that `c` is a class, do you think 
> I'd have any luck if I made it immutable?
The quick answer is that it doesn't help. DMD still doesn't like 
me using insertInPlace. This is a little disappointing as 
immutable is supposed to avoid the need for copying. Then again, 
I guess that's a compiler - not language - level affordance. 
Thanks again.

>
>>> In the short term, could anybody suggest a `static if` 
>>> expression to determine whether I can copy the type to the 
>>> satisfaction of `copyBackwards`? I tried isMutable but that 
>>> didn't seem to work.
>>>
>>> Thanks, John
>>
>> You probably want std.traits.isAssignable
>>
>>    pragma(msg, isAssignable!(S, S)); // False
> That's exactly what I was looking for. Thank you.


More information about the Digitalmars-d-learn mailing list