digitalmars.D.learn - array setting : Whats going in here?
- claptrap (8/8) Oct 06 2023 char[] foo;
- H. S. Teoh (13/23) Oct 06 2023 If you want initialization, don't slice the target array. For example:
- claptrap (4/10) Oct 07 2023 How did I not know that?? I'd always thought "foo[] = x" was just
- Jonathan M Davis (43/54) Oct 07 2023 It is, but it's assigning them to the elements in the slice, and if you
- Imperatorn (6/14) Oct 08 2023 Even though you now have gotten answers, I still agree with you
- Jonathan M Davis (26/41) Oct 08 2023 Except that in those examples, they _do_ match. It's perfectly valid to ...
- Imperatorn (2/13) Oct 09 2023 Thanks, I think I read the code a little too fast
char[] foo; foo.length = 4; foo[] = 'a'; // ok sets all elements foo[] = "a"; // range error at runtime? foo[] = "ab"; // range error at runtime? So I meant to init with a char literal but accidently used double quotes. Should that even compile? Shouldn't the compiler at least complain when trying to init with "ab"?
Oct 06 2023
On Sat, Oct 07, 2023 at 12:00:48AM +0000, claptrap via Digitalmars-d-learn wrote:char[] foo; foo.length = 4; foo[] = 'a'; // ok sets all elements foo[] = "a"; // range error at runtime? foo[] = "ab"; // range error at runtime? So I meant to init with a char literal but accidently used double quotes. Should that even compile? Shouldn't the compiler at least complain when trying to init with "ab"?If you want initialization, don't slice the target array. For example: char[] foo = "a"; Or: char[] foo; ... foo = "a"; When you write `foo[]` you're taking a slice of the array, and in that case if the lengths of both sides of the assignment don't match, you'll get a runtime error. T -- Always remember that you are unique. Just like everybody else. -- despair.com
Oct 06 2023
On Saturday, 7 October 2023 at 00:49:39 UTC, H. S. Teoh wrote:On Sat, Oct 07, 2023 at 12:00:48AM +0000, claptrap via Digitalmars-d-learn wrote:How did I not know that?? I'd always thought "foo[] = x" was just special syntax for setting all the elements to the same value. Thanks.When you write `foo[]` you're taking a slice of the array, and in that case if the lengths of both sides of the assignment don't match, you'll get a runtime error.
Oct 07 2023
On Saturday, October 7, 2023 10:59:47 AM MDT claptrap via Digitalmars-d-learn wrote:On Saturday, 7 October 2023 at 00:49:39 UTC, H. S. Teoh wrote:It is, but it's assigning them to the elements in the slice, and if you slice the entire array, then you're assigning to every element in the array. e.g. auto foo = new int[](6); foo[] = 5; assert(foo == [5, 5, 5, 5, 5, 5]); Alternatively, you can assign to a slice that refers to just some of the elements of the array being sliced. e.g. auto foo = new int[](6); foo[0 .. 3] = 5; assert(foo == [5, 5, 5, 0, 0, 0]); And if you're assigning another array to it rather than a value of the element type, then it assigns the individual elements. e.g. auto foo = new int[](6); auto bar = [1, 2, 3, 4]; foo[0 .. 4] = bar[]; assert(foo == [1, 2, 3, 4, 0, 0]); And when you assign an array/slice like that, the number of elements on each side must match. So, if you do any of foo[] = bar[]; or foo[] = bar; then foo and bar must have the same length (and must have compatible element types). The difference between those and foo = bar; is that assigning to foo[] results in the elements being copied, whereas assigning directly to foo results in foo being a slice of bar. auto foo = new int[](6); auto bar = new int[](6); foo[] = bar[]; assert(foo == bar); assert(foo !is bar); foo = bar[]; assert(foo is bar); So, it's probably best to think of foo[] = x; as being a way to assign to each individual element in that slice of foo rather than assigning to foo. And then which elements are assigned to depends on how much of foo you slice, and how those elements are assigned to depends on the type of x. - Jonathan M DavisOn Sat, Oct 07, 2023 at 12:00:48AM +0000, claptrap via Digitalmars-d-learn wrote: When you write `foo[]` you're taking a slice of the array, and in that case if the lengths of both sides of the assignment don't match, you'll get a runtime error.How did I not know that?? I'd always thought "foo[] = x" was just special syntax for setting all the elements to the same value. Thanks.
Oct 07 2023
On Saturday, 7 October 2023 at 00:00:48 UTC, claptrap wrote:char[] foo; foo.length = 4; foo[] = 'a'; // ok sets all elements foo[] = "a"; // range error at runtime? foo[] = "ab"; // range error at runtime? So I meant to init with a char literal but accidently used double quotes. Should that even compile? Shouldn't the compiler at least complain when trying to init with "ab"?Even though you now have gotten answers, I still agree with you that there should be some kind of "warning" or suggestion like, did you mean to assign incompatible types? It could just check the element type and see if it matches the rhs type.
Oct 08 2023
On Sunday, October 8, 2023 8:08:46 AM MDT Imperatorn via Digitalmars-d-learn wrote:On Saturday, 7 October 2023 at 00:00:48 UTC, claptrap wrote:Except that in those examples, they _do_ match. It's perfectly valid to copy elements of a string to a char[]. It's just copying immutable(char) to char. The compiler would complain if it couldn't implicitly convert the element type in the array being assigned from to the element type in the array being assigned to. The problem here is simply that the lengths of the arrays don't match. And in general, the compiler has no way of knowing whether the lengths match, because the lengths are dynamic. In this particular case, it could figure it out if it did sufficient flow analysis, but that's the sort of thing that typically isn't done in D, because it gets to be expensive and tends to result in inconsistent behavior, because small changes to the code could drastically change what the compiler is able to figure out. If the lengths were static, then the compiler actually would complain. e.g. foo[0 .. 3] = bar[1 .. 2]; would result in a compilation error such as q.d(5): Error: mismatched array lengths 3 and 1 for assignment `foo[0..3] = bar[1..2]` So, the compiler will complain both if it can't implicitly convert the element types to make the assignment work and if it can statically see that the lengths of the arrays don't much. As such, I'm not sure that there's actually anything that the compiler could do here to catch the problem in the OP's case (at least not without doing code flow analysis, which isn't going to happen). - Jonathan M Davischar[] foo; foo.length = 4; foo[] = 'a'; // ok sets all elements foo[] = "a"; // range error at runtime? foo[] = "ab"; // range error at runtime? So I meant to init with a char literal but accidently used double quotes. Should that even compile? Shouldn't the compiler at least complain when trying to init with "ab"?Even though you now have gotten answers, I still agree with you that there should be some kind of "warning" or suggestion like, did you mean to assign incompatible types? It could just check the element type and see if it matches the rhs type.
Oct 08 2023
On Monday, 9 October 2023 at 02:19:20 UTC, Jonathan M Davis wrote:On Sunday, October 8, 2023 8:08:46 AM MDT Imperatorn via Digitalmars-d-learn wrote:Thanks, I think I read the code a little too fast[...]Except that in those examples, they _do_ match. It's perfectly valid to copy elements of a string to a char[]. It's just copying immutable(char) to char. The compiler would complain if it couldn't implicitly convert the element type in the array being assigned from to the element type in the array being assigned to. The problem here is simply that the lengths of the arrays don't match. [...]
Oct 09 2023