Bug 671 – Class initialization should not call opAssign

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2006-12-09T19:31:00Z
Last change time
2014-02-15T13:19:31Z
Keywords
accepts-invalid
Assigned to
bugzilla
Creator
samukha

Comments

Comment #0 by samukha — 2006-12-09T19:31:37Z
This compiles and fails at runtime with access violation. Seems like opAssign gets called on the uninitialized class reference. class Test { int a; void opAssign(int v) { a = v; } } void main() { Test t = 20; }
Comment #1 by bugzilla — 2006-12-09T20:32:52Z
opAssign isn't for object construction. The object t was never created or constructed.
Comment #2 by ibisbasenji — 2006-12-09T23:41:11Z
(In reply to comment #1) > opAssign isn't for object construction. The object t was never created or > constructed. > No doubt, though I would argue this is one specific case the compiler could catch and issue an error on (attempt to initialize object variable with non-object). Either that or rewrite 'Class var = 42' as 'Class var = (new Class) = 42' such that it works with any class defining a default constructor. I'm not saying I'm fond of that idea (not entirely fond of opAssign at all) but it would seem a natural enough evolution.
Comment #3 by smjg — 2006-12-10T12:43:39Z
operatoroverloading.html "The assignment operator = can be overloaded if the lvalue is a struct or class aggregate, and opAssign is a member function of that aggregate." The assignment _operator_, that is. The "t = 20" of "Test t = 20;" is not an AssignExpression, or indeed any kind of expression, and so it's not using the assignment operator. It's a wholly distinct use of the "=" token from a code structure POV. If this were to be allowed, it would have to be explicitly specified that opAssign applies to initializers as well as AssignExpressions. Even then, unless as Chris suggests you make it equivalent to Test t = (new Test) = 20; then it makes no sense whatsoever to allow a class (as opposed to struct or union) variable to be initialized in this way.
Comment #4 by samukha — 2006-12-10T19:09:55Z
Actually, I discovered this bug while playing with dynamic struct initialization (having opCall and opAssign with the same signature in the test struct). I just replaced struct with class and wondered if the compiler choke. One of the following could fix the issue: 1. Disallow the syntax (Test t = (new Test) = 20; instead?); 2. Implicitly create a Test instance passing 20 to the ctor. class Test { int a; this(int v) { a = v; } } Test t = 20; // creates a Test and initializes a to 20; (bad idea) 3. Call 'static Test opCall(int);' on the class and assign the returned reference to t (similar to structs, bad idea)
Comment #5 by bugzilla — 2012-01-21T11:16:06Z
Stewart's right. This is construction, not assignment, and opAssign should not be called. Compiler bug, not spec problem.
Comment #6 by k.hara.pg — 2012-03-27T17:40:39Z
*** This issue has been marked as a duplicate of issue 7641 ***