www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Warning: explicit element-wise assignment (this.vector)[] = vec.vector[cast(ulong)0..cast(ulong)dimension]

reply David <d dav1d.de> writes:
I am getting lots of errors when compiling with -w:

// https://github.com/Dav1dde/gl3n/blob/master/gl3n/linalg.d#L144
    this(T)(T vec) if(is_vector!T && is(T.vt : vt) && (T.dimension >=
dimension)) {
        vector = vec.vector[0..dimension];
    }

this line produces following warning:

gl3n/linalg.d(144): Warning: explicit element-wise assignment
(this.vector)[] = vec.vector[cast(ulong)0..cast(ulong)dimension] is
better than this.vector = vec.vector[cast(ulong)0..cast(ulong)dimension]



Why does dmd produce this warning? (this is new in 2.063) Why is
assigning elementwise better?
Jun 24 2013
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, June 24, 2013 16:07:19 David wrote:
 I am getting lots of errors when compiling with -w:
 
 // https://github.com/Dav1dde/gl3n/blob/master/gl3n/linalg.d#L144
     this(T)(T vec) if(is_vector!T && is(T.vt : vt) && (T.dimension >=
 dimension)) {
         vector = vec.vector[0..dimension];
     }
 
 this line produces following warning:
 
 gl3n/linalg.d(144): Warning: explicit element-wise assignment
 (this.vector)[] = vec.vector[cast(ulong)0..cast(ulong)dimension] is
 better than this.vector = vec.vector[cast(ulong)0..cast(ulong)dimension]
 
 
 
 Why does dmd produce this warning? (this is new in 2.063) Why is
 assigning elementwise better?
According to the changelog ( http://dlang.org/changelog.html ), it sounds like it's because doing an element-wise copy is "arbitrarily expensive" (probably meaning O(n) rather than O(1)), so it potentially gave the false impression of being a simple, cheap assignment if the slicing syntax wasn't used. But I don't know what exactly went into that decision beyond what's listed in the changelog. - Jonathan M Davis
Jun 24 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
David:

 Why does dmd produce this warning? (this is new in 2.063) Why is
 assigning elementwise better?
The short answer is: do as the compiler suggests you, and be very happy the compiler avoids you some bugs. The explanation is longer. In brief, it's much better to avoid some bugs and to make the D semantics more clear, to denote all vector ops, including the assignment with a []. Bye, bearophile
Jun 24 2013
parent reply David <d dav1d.de> writes:
Am 24.06.2013 16:30, schrieb bearophile:
 David:
 
 Why does dmd produce this warning? (this is new in 2.063) Why is
 assigning elementwise better?
The short answer is: do as the compiler suggests you, and be very happy the compiler avoids you some bugs.
The problem is, I wrote this code on purpose and I *want* it to work like that, and I evenn need it to work like that (a few lines above in "construct"), but this currently blocks gl3n from beeing updated for Fedora.
 The explanation is longer. In brief, it's much better to avoid some bugs
 and to make the D semantics more clear, to denote all vector ops,
 including the assignment with a [].
What kind of bugs does it avoid? I can't think of a single bug which could happen... (Ranges/Lengths are checked at runtime...)
Jun 24 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
David:

 What kind of bugs does it avoid?
 I can't think of a single bug which could happen...
 (Ranges/Lengths are checked at runtime...)
Some reasons: - Syntax uniformity: similar behaviours should look similar. This is a general rule of language design, that avoids troubles you don't even know. All array ops use [], so it's right for vector assignment to use them. - The second rule is that in a language as D we want to denote different code complexities with different code. This is the reason given in the Changelog, and it explains while length and walkLength have different names. In past you were not able to tell from a look at the syntax what's happening: void main() { int[][3] x; int[] y; int[] z; x[] = z; // copies just the z pointer y[] = z; // copies the elements in z } More details: http://d.puremagic.com/issues/show_bug.cgi?id=7444 Coming from this older: http://d.puremagic.com/issues/show_bug.cgi?id=3971 You are welcome, bearophile
Jun 24 2013
parent David <d dav1d.de> writes:
Am 24.06.2013 22:50, schrieb bearophile:
 David:
 
 What kind of bugs does it avoid?
 I can't think of a single bug which could happen...
 (Ranges/Lengths are checked at runtime...)
Some reasons: - Syntax uniformity: similar behaviours should look similar. This is a general rule of language design, that avoids troubles you don't even know. All array ops use [], so it's right for vector assignment to use them. - The second rule is that in a language as D we want to denote different code complexities with different code. This is the reason given in the Changelog, and it explains while length and walkLength have different names. In past you were not able to tell from a look at the syntax what's happening: void main() { int[][3] x; int[] y; int[] z; x[] = z; // copies just the z pointer y[] = z; // copies the elements in z } More details: http://d.puremagic.com/issues/show_bug.cgi?id=7444 Coming from this older: http://d.puremagic.com/issues/show_bug.cgi?id=3971 You are welcome, bearophile
This really sucks... I guess I can workaround it with a "static" foreach and do an elementwise copy. Thanks for the explanation.
Jun 25 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/24/2013 12:17 PM, David wrote:

 The problem is, I wrote this code on purpose and I *want* it to work
 like that, and I evenn need it to work like that (a few lines above in
 "construct"), but this currently blocks gl3n from beeing updated for 
Fedora. You are right because 'vector' is a fixed-length array. So, the following two have the same effect: vector = vec.vector[0..dimension]; vector[] = vec.vector[0..dimension]; I don't know whether that is by design. One can argue that array-wise syntax should be recommended only for slices. In any case, as bearophile says, uniformity is always helpful. Ali
Jun 24 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Ali Çehreli:

 So, the following two have the same effect:

     vector = vec.vector[0..dimension];

     vector[] = vec.vector[0..dimension];
The first syntax will be deprecated and later it will become an error. Bye, bearophile
Jun 24 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/24/2013 03:12 PM, bearophile wrote:

 Ali Çehreli:

 So, the following two have the same effect:

     vector = vec.vector[0..dimension];

     vector[] = vec.vector[0..dimension];
The first syntax will be deprecated and later it will become an error.
I am confused. Even if the right-hand expression were a fixed-length array? If so, then we wouldn't speak of their being value types. (?) a = b; // should be fine Otherwise, fixed-length arrays would become weird types that cannot be used in assignment operations. I just read the change log. Either it is incorrect or the change is implemented inccorrectly because it is supposed to be about the right-hand side. So, OP's code is correct after all. Here is the excerpt from the change log: <excerpt> Array copy operations now always require using the slice syntax: The right-hand-side of an array copy operation now requires using the slice syntax: void main() { int[][2] x; int[] y; int[] z; x[] = z; // copies z (pointer + length) 2 times to x y[] = z; // copies each element of z into y (compiler emits warning) } If the user intended to write such code they must use the slice syntax for both the source and target arrays: void main() { int[][2] x; int[] y; int[] z; y[] = z[]; // copies each element of z into y (no warnings) } Rationale: The compiler will emit a warning to make the user aware that the copy operation is arbitrarily expensive. </excerpt> Ali
Jun 24 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Ali Çehreli:

 I am confused. Even if the right-hand expression were a 
 fixed-length array? If so, then we wouldn't speak of their 
 being value types. (?)

     a = b;    // should be fine

 Otherwise, fixed-length arrays would become weird types that 
 cannot be used in assignment operations.

 I just read the change log. Either it is incorrect or the 
 change is implemented inccorrectly because it is supposed to be 
 about the right-hand side. So, OP's code is correct after all.
Sorry, my mistake, I have confused the two things a bit, regarding the position of the []. Currently this code gives no warnings: void main() { int[3] a, b; a = b; } This topic is discussed a little in Issue 7444. Bye, bearophile
Jun 24 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/24/2013 04:11 PM, bearophile wrote:

 Currently this code gives no warnings:

 void main() {
      int[3] a, b;
      a = b;
 }

 This topic is discussed a little in Issue 7444.
http://d.puremagic.com/issues/show_bug.cgi?id=7444#c3 Summary: 1) Single element on the right-hand side is disallowed unless lhs is "all elements". One must write the following ("sa" is static array and "da" is dynamic array): sa[] = e; da[] = e; 2) Mixing static array and dynamic array on both sides of = is disallowed: sa[] = da[]; // fine: both dynamic arrays da[] = sa[]; // ditto da = sa[]; // ditto sa[] = da; // ditto Ali
Jun 24 2013
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/24/2013 05:16 PM, Ali Çehreli wrote:

 2) Mixing static array and dynamic array on both sides of = is 
disallowed:
    da[] = sa[];   // ditto
    da   = sa[];   // ditto
And I didn't mean that those two have the same meaning. The former is "copy all elements", and the latter is "refer to all of sa's elements". Ali
Jun 24 2013