digitalmars.D - Deprecate assigning a slice to a static array?
- Nick Treleaven (38/38) Aug 31 2022 I didn't know initializing a static array from a slice of unknown
- Nick Treleaven (5/6) Aug 31 2022 Here of course there is a runtime check that `s.length >= 2`. But
- Salih Dincer (25/28) Aug 31 2022 The reverse is also possible and note that .capacity is 0 in any
- Salih Dincer (3/5) Aug 31 2022 So is `slice` really a slice?
- bauss (2/8) Aug 31 2022 Yes, because a slice isn't a type but a concept.
- Nick Treleaven (11/14) Aug 31 2022 The above conversion would also be deprecated because
I didn't know initializing a static array from a slice of unknown length was allowed until I saw: https://dlang.org/blog/2022/06/21/dip1000-memory-safety-in-a-modern-system-programming-language-pt-1/ // allocated in static program memory auto hello1 = "Hello world!"; // allocated on the stack, copied from hello1 immutable(char)[12] hello2 = hello1; How does the compiler know `hello1.length` at compile-time for the initialisation of the static array? It doesn't - there is a runtime check. I think it's better to require slicing of either the static array or the slice to make that clear: int[] s = ...; int[2] a; a[] = s; // copy slice to slice, checking lengths match a = s[0..2]; // copy 2 elements, no runtime check (The last line is recognised as a slice of compile-time known length - described here: https://dlang.org/spec/expression.html#slice_to_static_array). For just `a = s;`, the programmer may have accidentally assumed `s` was a static array, or forgot to slice it to match the static array size. I think it's bug prone. It's also hard to detect if the slice normally has a matching length but in some weird runtime condition it doesn't and it throws. It's also a hidden runtime check that could hurt performance. Note this doesn't seem to be documented in the spec yet: [1] https://dlang.org/spec/arrays.html#assignment [2] https://dlang.org/spec/arrays.html#array-copying [3] https://dlang.org/spec/arrays.html#array-initialization [1] actually has: //s = a; // error, as a's length is not known at compile-time I added that to the docs but it's wrong (if this feature is to stay I will make a PR to fix that line). [2] only talks about slices. [3] doesn't mention initializing from an lvalue. *AssignExpression* just links to Array Copying [2] and Array Setting (for assigning a single element). Would deprecating this break much code? Perhaps an exploratory dmd PR could be made to see if it breaks any of the tested key projects?
Aug 31 2022
On Wednesday, 31 August 2022 at 12:04:10 UTC, Nick Treleaven wrote:a = s[0..2]; // copy 2 elements, no runtime checkHere of course there is a runtime check that `s.length >= 2`. But it is clearer the check is happening and the user could avoid that check with `.ptr`.
Aug 31 2022
On Wednesday, 31 August 2022 at 12:04:10 UTC, Nick Treleaven wrote:I didn't know initializing a static array from a slice of unknown length was allowed until I saw: https://dlang.org/blog/2022/06/21/dip1000-memory-safety-in-a-modern-system-programming-language-pt-1/The reverse is also possible and note that .capacity is 0 in any case. ```d // D 2.0.83 import std.stdio; void main() { int[4] abcd = [0, 1, 2, 3]; int[] slice = abcd[]; slice.writeln(": ", slice.capacity); int[] dcba = [ 7, 6, 5, 4, 3, 2, 1, 0]; int[4] arr = dcba[4..$]; arr.writeln(": ", arr.capacity); arr = dcba[0..4]; arr.writeln(": ", arr.capacity); }/* [0, 1, 2, 3]: 0 [3, 2, 1, 0]: 0 [7, 6, 5, 4]: 0 Process finished. */ ``` SDB 79
Aug 31 2022
On Wednesday, 31 August 2022 at 15:36:54 UTC, Salih Dincer wrote:The reverse is also possible and note that .capacity is 0 in any case.So is `slice` really a slice? SDB 79
Aug 31 2022
On Wednesday, 31 August 2022 at 15:41:14 UTC, Salih Dincer wrote:On Wednesday, 31 August 2022 at 15:36:54 UTC, Salih Dincer wrote:Yes, because a slice isn't a type but a concept.The reverse is also possible and note that .capacity is 0 in any case.So is `slice` really a slice? SDB 79
Aug 31 2022
On Wednesday, 31 August 2022 at 15:36:54 UTC, Salih Dincer wrote:int[] dcba = [ 7, 6, 5, 4, 3, 2, 1, 0]; int[4] arr = dcba[4..$];The above conversion would also be deprecated because `dcba[4..$]` is not one of the slice expression forms with compile-time known length (the compiler doesn't know what `$` is). `dcba[4..8]` could be used instead. In case the runtime matching length check is desired with static array initialization (i.e. check `dcba.length` is not > 8), it would be written as: int[4] arr; // optimizer can remove `= 0` arr[] = dcba[4..$]; // matching length check now more obviousarr = dcba[0..4];That is fine as I mentioned, it's one of the forms recognised.
Aug 31 2022