Jump to page: 1 2 3
Thread overview
[Issue 7021] New: Structs with disabled default constructors can be constructed without calling a constructor.
Nov 27, 2011
Simen Kjaeraas
Jul 10, 2012
Jonathan M Davis
Jul 28, 2012
Jonathan M Davis
Sep 21, 2012
Simen Kjaeraas
Sep 21, 2012
Kenji Hara
Sep 21, 2012
Kenji Hara
Sep 21, 2012
Simen Kjaeraas
Sep 21, 2012
Jonathan M Davis
Sep 21, 2012
Maxim Fomin
Sep 21, 2012
Kenji Hara
Sep 21, 2012
Jonathan M Davis
Sep 22, 2012
Kenji Hara
Sep 22, 2012
Jonathan M Davis
Sep 22, 2012
Kenji Hara
Sep 22, 2012
Jonathan M Davis
Sep 24, 2012
Don
Sep 24, 2012
Jonathan M Davis
Sep 24, 2012
Kenji Hara
Sep 24, 2012
Kenji Hara
Oct 28, 2012
yebblies
November 27, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=7021

           Summary: Structs with disabled default constructors can be
                    constructed without calling a constructor.
           Product: D
           Version: D2
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: simen.kjaras@gmail.com


--- Comment #0 from Simen Kjaeraas <simen.kjaras@gmail.com> 2011-11-27 13:23:25 PST ---
struct Foo {
    @disable this();
}

void main() {
    auto foo = Foo();
}

The above code compiles and runs just fine on dmd 2.056.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 10, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021


Jonathan M Davis <jmdavisProg@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg@gmx.com
           Severity|normal                      |major


--- Comment #1 from Jonathan M Davis <jmdavisProg@gmx.com> 2012-07-09 20:22:25 PDT ---
This works just fine too (with dmd 2.060HEAD)

struct Foo
{
    @disable this();
}

void main()
{
    auto foo = Foo.init;
}

It looks to me like @disable this() isn't working at all.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 28, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021



--- Comment #2 from Jonathan M Davis <jmdavisProg@gmx.com> 2012-07-27 17:30:18 PDT ---
*** Issue 8457 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021


Simen Kjaeraas <simen.kjaras@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |k.hara.pg@gmail.com


--- Comment #3 from Simen Kjaeraas <simen.kjaras@gmail.com> 2012-09-21 06:06:56 PDT ---
*** Issue 8703 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021



--- Comment #4 from Kenji Hara <k.hara.pg@gmail.com> 2012-09-21 06:26:06 PDT ---
(In reply to comment #1)
> This works just fine too (with dmd 2.060HEAD)
> 
> struct Foo
> {
>     @disable this();
> }
> 
> void main()
> {
>     auto foo = Foo.init;
> }
> 
> It looks to me like @disable this() isn't working at all.

I think that built-in init property should be valid even if default ctor is
disabled.
T.init shows runtime object initial bit-wise representation. So, in this case,
Foo.init would be 1 byte zero filled memory, and should be accessible even if
Foo is not default constructible.

But T.init sometimes does not *valid* object. See following example.

struct Bar
{
    int value;

    @disable this();
    this(int v) { assert(v > 0); value = v; }
}

Bar's constructor appeals that Bar.value is initialized with natural number.
But Bar.init.value == 0, because it doesn't call valid ctor. Then T.init is
*invalid* object.
This is not a defect of D language, but also it is a point you should be
careful.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021


Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull
           Platform|Other                       |All


--- Comment #5 from Kenji Hara <k.hara.pg@gmail.com> 2012-09-21 06:29:17 PDT ---
https://github.com/D-Programming-Language/dmd/pull/1132

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021



--- Comment #6 from Simen Kjaeraas <simen.kjaras@gmail.com> 2012-09-21 07:30:39 PDT ---
(In reply to comment #4)
> I think that built-in init property should be valid even if default ctor is
> disabled.
> T.init shows runtime object initial bit-wise representation. So, in this case,
> Foo.init would be 1 byte zero filled memory, and should be accessible even if
> Foo is not default constructible.

I agree, seeing as T.init can be @disabled. If someone really, *really* needs a T without calling its constructor, there are still ways.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021



--- Comment #7 from Jonathan M Davis <jmdavisProg@gmx.com> 2012-09-21 08:51:34 PDT ---
Wait.

@disable this();

_is_ the way to disable init. If

@diasble this();

was used, then there should be no init property. That's the entire point of

@disable this;

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021


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

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


--- Comment #8 from Maxim Fomin <maxim@maxim-fomin.ru> 2012-09-21 09:18:39 PDT ---
(In reply to comment #7)
> Wait.
> 
> @disable this();
> 
> _is_ the way to disable init. If
> 
> @diasble this();
> 
> was used, then there should be no init property. That's the entire point of
> 
> @disable this;

Why? .init is a property which currently (2.060) can be hijacked. Dmd seems not
to generate an implicit constructor function, it just initialize raw memory
with default values when it faces S(). This is why disabling any function
(ctors too) doesn't prevent it from creating S object.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021



--- Comment #9 from Kenji Hara <k.hara.pg@gmail.com> 2012-09-21 09:38:44 PDT ---
(In reply to comment #7)
> Wait.
> 
> @disable this();
> 
> _is_ the way to disable init. If
> 
> @diasble this();
> 
> was used, then there should be no init property. That's the entire point of
> 
> @disable this;

I think that using T.init does not call any constructors. Therefore any constructor declarations cannot stop its using.

----

I think a struct that has @disable this(); is similar to nested struct that used outside of the valid scope.

void main() {
  struct S {  // nested struct
    int n; void foo(){}
  }
  static assert(is(typeof(S.init.tupleof[$-1]) == void*));  // hidden frame ptr
  check!S();
}
void check!T() {
  T t1;  // today this is rejected by fixing issue 8339
  T t2 = T.init; // this is still valid
  assert(t2.tupleof[$-1] is null); // but hidden frame ptr is null
  // then, t2 is *invalid* object.
}

On the other hand, even if @disable this(); is declared, init property exists.

struct S {
  @disable this();    // disable default construction
  this(int n) {  // valid construction with a parameter
    // in here, the memory of 'this' is filled with *S.init*.
    ...logical initialization of 'this' object with ctor parameters...
  }
}

T.init property does not guarantee that the returned object is logically correctly initialized, but it always provides the initial bit representation of T. I think this rule is reasonable also for @disable this(); struct.

Of course, you can select a following design:
"If struct has @disable this(); *and* no other ctors, init property is also
disabled."
But, it seems to me that is a special case which reduces the orthogonality and
increase the complexity.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2 3