Bug 17729 – dmd says cast expression is "not an lvalue", but it can be used as one in other contexts

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-08-07T22:12:28Z
Last change time
2019-05-25T13:08:28Z
Assigned to
RazvanN
Creator
ag0aep6g
See also
https://issues.dlang.org/show_bug.cgi?id=19754

Comments

Comment #0 by ag0aep6g — 2017-08-07T22:12:28Z
As requested by Andrei on GitHub (<https://github.com/dlang/druntime/pull/1605#discussion_r131770687>). Taking the address of a cast expression gets rejected: ---- struct S { int field = 0; } void main() { shared S s; auto p = & cast(S) s; /* Error: cast(S)s is not an lvalue */ } ---- But we can take the address of the field and it's the same as `s`'s: ---- struct S { int field = 0; } void main() { shared S s; auto p = &(cast(S) s).field; *p = 1; assert(s.field == 1); } ---- We can even use the cast expression on the left-hand side of an assignment: ---- struct S { int field = 0; } void main() { shared S s; cast(S) s = S(1); /* no error */ assert(s.field == 1); /* passes */ } ---- Either all snippets should be rejected, or they should all be accepted.
Comment #1 by er.krali — 2018-09-19T15:22:55Z
Furthermore, it doesn't work with ref parameters either: --- struct S { int i; } void fun(ref S s, int i) { s.i = i; } void main() { shared S s; /* This fails: onlineapp.d(17): Error: function onlineapp.fun(ref S s, int i) is not callable using argument types (S, int) onlineapp.d(17): cannot pass rvalue argument cast(S)s of type S to parameter ref S s fun(cast(S) s, 1); */ (*(cast (S*) &s)).fun(1); // Nasty workaround assert (s.i == 1); } --- I also can't understand why the workaround works at all, the result of dereferencing a pointer should surely be a rvalue? Is that also a bug?
Comment #2 by ag0aep6g — 2018-09-19T16:39:33Z
(In reply to er.krali from comment #1) > I also can't understand why the workaround works at all, the result of > dereferencing a pointer should surely be a rvalue? > > Is that also a bug? Dereferencing a pointer gives an lvalue. If it gave an rvalue, pointers would be pretty useless. You couldn't assign through them. If you disagree or have more questions on this, I'd suggest making a thread on D.learn [1]. We're going off topic here. [1] https://forum.dlang.org/group/learn
Comment #3 by er.krali — 2018-09-19T16:45:52Z
(In reply to ag0aep6g from comment #2) > Dereferencing a pointer gives an lvalue. If it gave an rvalue, pointers > would be pretty useless. You couldn't assign through them. > > If you disagree or have more questions on this, I'd suggest making a thread > on D.learn [1]. We're going off topic here. > > > [1] https://forum.dlang.org/group/learn Sure, now that I think about it, it seems indeed obvious, sorry for the OT.
Comment #4 by ag0aep6g — 2019-05-25T13:08:28Z
This has apparently been fixed by the fix for issue 19754. `auto p = & cast(S) s;` compiles now. Closing as duplicate. *** This issue has been marked as a duplicate of issue 19754 ***