Bug 12211 – Assignment expression is not an lvalue
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-02-19T23:07:00Z
Last change time
2014-04-26T20:20:57Z
Keywords
pull
Assigned to
nobody
Creator
k.hara.pg
Comments
Comment #0 by k.hara.pg — 2014-02-19T23:07:58Z
Test case:
void main()
{
int a;
void foo(ref int x) { assert(&x == &a); }
foo(a += 1); // OK
//foo(a = 1); // doesn't compile
}
Comment #1 by k.hara.pg — 2014-02-20T21:07:40Z
In C++:
#include <stdio.h>
void foo(int& x)
{
printf("foo: x = %d\n", x);
x = 3;
}
int main()
{
int a = 0;
printf("a = %d\n", a);
foo(a += 1);
printf("a = %d\n", a);
foo(a = 2);
printf("a = %d\n", a);
}
Prints:
---
a = 0
foo: x = 1
a = 3
foo: x = 2
a = 3
Comment #2 by k.hara.pg — 2014-02-20T21:33:01Z
Note that, "an assignment expression should make an lvalue" will be consistent with the behavior of the implicitly generated opAssign methods for user defined structs.
import core.stdc.stdio;
struct S
{
this(this) { printf("postblit\n"); }
}
void main()
{
S a;
S b;
pragma(msg, typeof(S.opAssign));
// Prints: pure nothrow ref @safe S(S p)
// So, the implicitly generated opAssign returns the reference of the
// assigned value.
b = (a = S());
// is translated to: b(a.opAssign(S()))
// and the lvalue a.opAssign(S()) makes a copy.
// Therefore, in runtime this line will print one "postblit".
}