Array operations with array of structs

ketmar via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jul 7 23:05:51 PDT 2015


On Tue, 07 Jul 2015 11:09:52 +0000, Peter wrote:

> Any ideas about what's happening?

yes. there is code in "arrayop.c" that tells:

     // Built-in array ops should be @trusted, pure, nothrow and 
nogc
     StorageClass stc = STCtrusted | STCpure | STCnothrow | 
STCnogc;

under the hoods compiler rewrites `f[] = c[]+d[];` to this:

_arraySliceSliceAddSliceAssign_S3z007Vector3 extern (C) Vector3[]
   (Vector3[] p2, const Vector3[] p1, const Vector3[] p0)
   pure nothrow @nogc @trusted
   {
     foreach (p; 0u .. p2.length) {
       p2[p] = cast(Vector3)(p0[p] + p1[p]);
     }
     return p2;
   }

   _arraySliceSliceAddSliceAssign_S3z007Vector3(f, c, d);

do you see the gotcha? if you uncomment postblit or assigns, this 
build function fails to compile, as that operations aren't "pure 
nothrow @nogc @trusted", and they will be used for either assign 
or postblitting.

the same will happen if you add anything to your `opBinary` which 
make it unpure/@system (like `writeln`, for example). i.e.

   Vector3 opBinary(string op : "+") (in Vector3 rhs) const {
     import std.stdio; writeln("opBinary"); // (1)
     Vector3 result;
     result.vdata[] = this.vdata[] + rhs.vdata[];
     return result;
   }

BOOM! adding (1) is enough to get the same error.

this is what is going on. i don't know why DMD insists on such 
restrictions for array operations, though.


More information about the Digitalmars-d-learn mailing list