www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 671] New: Weird class reference declaration compiles

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=671

           Summary: Weird class reference declaration compiles
           Product: D
           Version: 0.177
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: maxter i.com.ua


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;
}


-- 
Dec 09 2006
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=671


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID




------- Comment #1 from bugzilla digitalmars.com  2006-12-09 20:32 -------
opAssign isn't for object construction. The object t was never created or
constructed.


-- 
Dec 09 2006
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=671





------- Comment #2 from ibisbasenji gmail.com  2006-12-09 23:41 -------
(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. --
Dec 09 2006
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=671


smjg iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com
             Status|RESOLVED                    |REOPENED
           Keywords|                            |accepts-invalid, spec
         Resolution|INVALID                     |




------- Comment #3 from smjg iname.com  2006-12-10 12:43 -------
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.


-- 
Dec 10 2006
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=671





------- Comment #4 from maxter i.com.ua  2006-12-10 19:09 -------
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)


-- 
Dec 10 2006