Issue 24355 - Slice copy with static arrays incorrect bounds checking
Summary: Slice copy with static arrays incorrect bounds checking
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 All
: P1 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-01-25 19:43 UTC by ryuukk_
Modified: 2024-01-26 14:09 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description ryuukk_ 2024-01-25 19:43:57 UTC
## Case 1:

```
void main()
{
    char[32] id = 0;
    const(char)* str = "hello";

    id = str[0 .. 6];
}
```


id is large enough for the string "hello", it should compile instead i get:

``
Error: mismatched array lengths 32 and 6 for assignment `id[] = str[0..6]
``



## Case 2:


```
void main()
{
    char[4] id;
    id = "hello asdad";
}
```

is not not large enough, both string and array length are known at compile time, this shouldn't compile error should be:

``
Error: mismatched array lengths 4 and 1 for assignment `id[] = "hello asdad"
``
Comment 1 anonymous4 2024-01-25 20:02:42 UTC
In case 1 it's unclear what you want, it can be id[0..6]=str[0..6] or id[0..6]=str[0..6],id[6..12]=str[0..6],... - pattern copy.
Comment 2 ryuukk_ 2024-01-25 20:51:18 UTC
I expect the same as:

```
void main()
{
    char[32] id = "hello";
}
```



left: static array
right: slice

result: slice -> copy -> [0 .. slice.length]
Comment 3 Nick Treleaven 2024-01-26 12:44:18 UTC
    char[32] id = 0;
    const(char)* str = "hello";
    id = str[0 .. 6];

The error is correct by the spec:
> A static array can be assigned from a dynamic array - the data is copied. The lengths must match
https://dlang.org/spec/arrays.html#assignment

    char[4] id;
    id = "hello asdad";

This causes a runtime error. You're right it could be caught at compile-time. Assigning an array literal with excess elements is a compile error.

    char[32] id = "hello";

An array *initializer* is allowed to have fewer elements. If there are excess elements, for an array literal it's a compile error, for a string literal, it's a runtime error as above.
Comment 4 Nick Treleaven 2024-01-26 12:57:06 UTC
> An array *initializer* is allowed to have fewer elements.

Actually that only seems to apply when the initializer is a string literal.

char[4] s = [1]; // error
char[4] s = "a"; // OK
Comment 5 Nick Treleaven 2024-01-26 14:09:06 UTC
Spec for above:

> A string literal converts to a static array rvalue of the same or longer length
https://dlang.org/spec/expression.html#string_literals