www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9372] New: Class member with disabled ctor makes class ctor unusable

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

           Summary: Class member with  disabled ctor makes class ctor
                    unusable
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: hsteoh quickfur.ath.cx


--- Comment #0 from hsteoh quickfur.ath.cx 2013-01-22 12:00:45 PST ---
Code:

-----------SNIP-------------
import std.stdio;

struct Trouble {
         disable this();
         disable this(this);

        int dummy;

        this(int x) {
                dummy = x;
        }
}

class Room {
        Trouble t;

        this() {
                t = Trouble(123);
        }
}

void main() {
        auto r = new Room; // this is line 23
}
-----------SNIP-------------

Compiler error:
-----------SNIP-------------
test.d(23): Error: default construction is disabled for type Room
-----------SNIP-------------

Commenting out the  disabled lines in Trouble makes the problem go away.

This behaviour makes no sense. The class ctor is a default ctor which calls the
Trouble ctor with non-default arguments, so it should be allowed. I can see
where this shouldn't be allowed (if Room is another struct for, example), but
since Room is a class, this should be allowed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 22 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9372


Jacob Carlborg <doob me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |doob me.com


--- Comment #1 from Jacob Carlborg <doob me.com> 2013-01-22 23:34:19 PST ---
I don't know if this makes any sense but:

When the code "new Room" is run the runtime will first create a new instance of
"Room" and initialize all fields. It will then run the constructor. Technically
you don't need to run the constructor at all, I don't do that in my
serialization library. The field "t" cannot be initialized because it has its
default constructor disabled. I'm not sure if the default constructor of
Trouble is the same as "Trouble.init". If not, I think this should compile. If
it is the same, then this error perhaps makes sense.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 22 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9372



--- Comment #2 from hsteoh quickfur.ath.cx 2013-01-23 07:52:50 PST ---
(In reply to comment #1)

Maybe it makes sense on some level, perhaps from the implementation POV, but to
me, a language-level user, it makes no sense at all, because a ctor is supposed
to be what initializes the class instance.

Furthermore, a class with a ctor that takes more than zero parameters causes
"auto x = new Class;" to be rejected, because the ctor cannot be called with no
arguments. So to me, this indicates that the ctor will always be called (as
expected); the compiler never says "OK you called new with no parameters, I'll
just default-initialize all your class fields". Since this is the case, it
makes no sense to now suddenly require that all fields be
default-initializable. It has always been the ctor's job to initialize all
fields.

(In fact that's why I chose to use a class instead of a struct, since structs
can be declared without calling any ctors.)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 23 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9372



--- Comment #3 from hsteoh quickfur.ath.cx 2013-01-23 07:55:10 PST ---
P.S. Even Object.factory does not allow the creation of objects without a
default ctor, so I'd argue that in no case should the implementation require
that all class fields be default-initializable when there's already a ctor to
do the job.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 23 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9372



--- Comment #4 from Jacob Carlborg <doob me.com> 2013-01-23 08:02:58 PST ---
(In reply to comment #3)
 P.S. Even Object.factory does not allow the creation of objects without a
 default ctor, so I'd argue that in no case should the implementation require
 that all class fields be default-initializable when there's already a ctor to
 do the job.

Then that will break a lot of the safety D provides with its default initialized variables. Example: class Foo { int a; // assume this is not initialized this () { writeln(a); // writes garbage } } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 23 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9372



--- Comment #5 from hsteoh quickfur.ath.cx 2013-01-23 08:14:47 PST ---
It should be illegal to reference an uninitialized variable in the ctor.
Something similar to how immutable fields are handled can be applied here:
you're not allowed to read the value of an immutable field until it's
initialized, and it can only be written to once.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 23 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9372



--- Comment #6 from Jacob Carlborg <doob me.com> 2013-01-23 11:57:38 PST ---
(In reply to comment #5)
 It should be illegal to reference an uninitialized variable in the ctor.
 Something similar to how immutable fields are handled can be applied here:
 you're not allowed to read the value of an immutable field until it's
 initialized, and it can only be written to once.

The following code with compiles DMD 2.061 and when it runs it prints "0". import std.stdio; class Foo { immutable int a; this () { writeln(a); a = 3; } } void main () { new Foo; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 23 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9372


Maxim Fomin <maxim maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |maxim maxim-fomin.ru


--- Comment #7 from Maxim Fomin <maxim maxim-fomin.ru> 2013-01-24 04:02:57 PST
---
The issue is debatable, but code below should be supported;

import std.stdio;

struct Trouble {
         disable this();
         disable this(this);

        int dummy;

        this(int x) {
                dummy = x;
        }
}

class Room {
        Trouble t = Trouble(123); // this should work

        this() {
                //t = Trouble(123);
        }
}

void main() {
        auto r = new Room; // this is line 23
}

Current situation shows either limitation of new implementation (druntime) or
design.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 24 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9372



--- Comment #8 from Jacob Carlborg <doob me.com> 2013-01-24 04:43:05 PST ---
(In reply to comment #7)
 The issue is debatable, but code below should be supported;
 
 import std.stdio;
 
 struct Trouble {
          disable this();
          disable this(this);
 
         int dummy;
 
         this(int x) {
                 dummy = x;
         }
 }
 
 class Room {
         Trouble t = Trouble(123); // this should work
 
         this() {
                 //t = Trouble(123);
         }
 }
 
 void main() {
         auto r = new Room; // this is line 23
 }
 
 Current situation shows either limitation of new implementation (druntime) or
 design.

I think that should work. The constructor does not initialize the fields, it's done before the constructor is called. This works: extern (C) Object _d_newclass(in ClassInfo); class Room { int i = 3; this (int f) {} } void main () { auto room = cast(Room) _d_newclass(Room.classinfo); assert(room.i == 3); } The constructor is not called but the field is initialized anyway. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 24 2013