Bug 13574 – incorrect code for assignment to dollar in slice expression
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-10-04T13:11:00Z
Last change time
2015-02-18T03:38:04Z
Keywords
accepts-invalid, pull
Assigned to
nobody
Creator
code
Comments
Comment #0 by code — 2014-10-04T13:11:58Z
cat > bug.d << CODE
extern (C) int printf(const char*, ...);
struct Foo
{
void opSlice(size_t a, size_t b) { printf("%zu %zu\n", a, b); }
alias opDollar = length;
size_t length;
}
void main()
{
Foo foo;
foo[0 .. foo.length = 1];
assert(foo.length == 1);
foo[0 .. $ = 2]; // assigns to the temporary dollar variable
assert(foo.length == 2);
}
CODE
dmd -run bug
----
AFAIK we're currently caching the result of opDollar to avoid reevaluating of side-effects. If that should remain the case the opDollar tmp variable needs to be const.
Alternatively we could also allow side-effects in opDollar (requires strict left to right evaluation) and not cache the value. This might be a bad choice when length is costly to compute.
Comment #1 by hsteoh — 2014-10-05T14:16:59Z
According to the current spec, the result of opDollar is cached:
http://dlang.org/operatoroverloading.html#dollar
(FYI, I was responsible for that particular note, under request by Kenji.)
I think assigning to $ in a slice expression should be illegal, since it leads to unclear semantics, e.g., what should arr[($=2) + ($=1)] mean?
Comment #2 by k.hara.pg — 2014-10-06T13:26:03Z
I think the "$' should be handled as an rvalue, therefoe $ should not be assignable.
I think this is not only an issue for opDollar, but also for dynamic arrays.
void main()
{
int[] arr = [1,2,3];
auto x = arr[0 .. arr.length = 1];
assert(arr.length == 1);
auto y = arr[0 .. $ = 2];
assert(arr.length != 2 && arr.length == 1); // pass
}
It's weird behavior, so I think all $ should not be assignable.
Compiler fix:
https://github.com/D-Programming-Language/dmd/pull/4045
Comment #3 by github-bugzilla — 2014-10-06T14:09:07Z