digitalmars.D.bugs - [Issue 7021] New: Structs with disabled default constructors can be constructed without calling a constructor.
- d-bugmail puremagic.com (24/24) Nov 27 2011 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (20/20) Jul 09 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (6/6) Jul 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (10/10) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (23/36) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (11/11) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (8/13) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (11/11) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (14/25) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (40/51) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (28/28) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (30/60) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (10/10) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (20/22) Sep 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (9/10) Sep 21 2012 Well, that's disgusting. There are way too many special cases here. I'd ...
- d-bugmail puremagic.com (12/31) Sep 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (12/13) Sep 24 2012 for example. defaultInitLiteral() is wrong.
- d-bugmail puremagic.com (8/10) Sep 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (10/12) Sep 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (61/61) Sep 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (13/13) Oct 11 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
- d-bugmail puremagic.com (10/10) Oct 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7021
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: -------
Nov 27 2011
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: -------
Jul 09 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: -------
Jul 27 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: -------
Sep 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: -------
Sep 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: -------
Sep 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: -------
Sep 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: -------
Sep 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: -------
Sep 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: -------
Sep 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #10 from Jonathan M Davis <jmdavisProg gmx.com> 2012-09-21 12:19:15 PDT --- It was my understanding that disable this(); was specifically the syntax to disable the init property. Certainly, trying to disable init directly doesn't work as far as I can tell. And since structs don't _have_ default constructors, I don't know what else disable this(); would be disabling (other than perhaps S(), which uses the init property anyway, since there's no default consturctor). The whole point is to be able disable init so that you can _never_ use it for _anything_. You must _always_ directly initialize such a type (unless you directly initialize it with void). Yes, normally, T.init is the value that the type has before any constructor is called, but if it's disabled, then it effectively does not exist, and it should be impossible to use T.init _anywhere_. Construction should work the same with any constructors that do exist (so the object state prior to construction is the same as what T.init would have been had it existed), but it should be impossible to default initialize such a type or to use it in any context which would require default initialization, and it should be impossible to reference that type's init in code anywhere. That's the whole point of disabling init, and disable this(); is specifically for disabling init. It doesn't affect declared constructors work, but it affects every other aspect of init. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #11 from Kenji Hara <k.hara.pg gmail.com> 2012-09-21 19:40:51 PDT --- (In reply to comment #10)It was my understanding that disable this(); was specifically the syntax to disable the init property. Certainly, trying to disable init directly doesn't work as far as I can tell. And since structs don't _have_ default constructors, I don't know what else disable this(); would be disabling (other than perhaps S(), which uses the init property anyway, since there's no default consturctor).I think disable this(); _does_ disables just a default constructor, and doesn't disable init property. As long as I repeated, init property represents a initial state of the object. (In the language reference, it is called 'default initializer'; http://dlang.org/property.html#init ). My first point is: init property does not construct anything. Next, if any constructor is declared in struct S, S(...) is always calls the constructors, and _should not_ become struct literal expression. This is my second point. S() would call this(), but it is disabled, then the compiler show an error so disable function is used. The third point is: the first and second are orthogonal. So I can agree that disable this(); would forbid a usage of S(), but I don't think that S.init would also be forbidden.The whole point is to be able disable init so that you can _never_ use it for _anything_. You must _always_ directly initialize such a type (unless you directly initialize it with void). Yes, normally, T.init is the value that the type has before any constructor is called, but if it's disabled, then it effectively does not exist, and it should be impossible to use T.init _anywhere_. Construction should work the same with any constructors that do exist (so the object state prior to construction is the same as what T.init would have been had it existed), but it should be impossible to default initialize such a type or to use it in any context which would require default initialization, and it should be impossible to reference that type's init in code anywhere. That's the whole point of disabling init, and disable this(); is specifically for disabling init. It doesn't affect declared constructors work, but it affects every other aspect of init.There is a way to disable explicit init property usage. struct S { disable this(); // disable default construction disable enum int init; // dummy disabled init property, this is allowed ... } I think that the usage of S.init is at your own risk. S.init may generate invalid object, but it is sometimes useful. I hesitate that stopping such usage by the compiler. At least, S() would be disabled by disable this(); declaration. It is the point of this issue, and my pull request will fix it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #12 from Jonathan M Davis <jmdavisProg gmx.com> 2012-09-21 19:48:34 PDT --- For structs, as long as there is no static opCall declared, S() and S.init should be identical, and I'd strongly argue that if one is disabled, the other should be disabled. They do exactly the same thing. It makes _no_ sense IMHO to allow S.init but allow S() or vice versa (as long as no static opCall is declared). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #13 from Kenji Hara <k.hara.pg gmail.com> 2012-09-21 20:19:53 PDT --- (In reply to comment #12)For structs, as long as there is no static opCall declared, S() and S.init should be identical,This is not already true for nested structs. void main() { int g = 10; struct S { int n; auto foo(){ return g; } } auto s1 = S(); // StructLiteralExp assert(s1.tupleof[$-1] !is null); // hidden ptr is filled assert(s1.foo() == 10); // OK auto s2 = S.init; assert(s2.tupleof[$-1] is null); // hidden ptr isn't filled assert(s2.foo() == 10); // Access Violation! } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #14 from Jonathan M Davis <jmdavisProg gmx.com> 2012-09-21 21:10:52 PDT ---This is not already true for nested structs.Well, that's disgusting. There are way too many special cases here. I'd vote to just make S() identical to S.init even with nested structs. It's more consistent that way, especially since you can't have a default constructor making it so that S() can't possible refer to a default constructor. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 Don <clugdbug yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |clugdbug yahoo.com.au --- Comment #15 from Don <clugdbug yahoo.com.au> 2012-09-24 06:31:57 PDT --- (In reply to comment #13)(In reply to comment #12)That's a bug: .init for nested structs is garbage. It's the cause of bug 6419, for example. defaultInitLiteral() is wrong. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------For structs, as long as there is no static opCall declared, S() and S.init should be identical,This is not already true for nested structs. void main() { int g = 10; struct S { int n; auto foo(){ return g; } } auto s1 = S(); // StructLiteralExp assert(s1.tupleof[$-1] !is null); // hidden ptr is filled assert(s1.foo() == 10); // OK auto s2 = S.init; assert(s2.tupleof[$-1] is null); // hidden ptr isn't filled assert(s2.foo() == 10); // Access Violation! }
Sep 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #16 from Jonathan M Davis <jmdavisProg gmx.com> 2012-09-24 08:32:45 PDT ---That's a bug: .init for nested structs is garbage. It's the cause of bug 6419,for example. defaultInitLiteral() is wrong. Then I _definitely_ think that S() and S.init should always be the same for structs as long as static opCall has not been declared, and disable this(); should disable S.init such that it's impossible to ever default-initialize S or to use S.init or to use S() (though S() should still work if static opCall is declared). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #17 from Kenji Hara <k.hara.pg gmail.com> 2012-09-24 08:47:32 PDT --- (In reply to comment #15)That's a bug: .init for nested structs is garbage. It's the cause of bug 6419, for example. defaultInitLiteral() is wrong.Hmmm? Now all cases in bug 6419 run correctly. In current, by fixing bug 7965, TypeStruct::defaultInitLiteral always returns StructLiteralExp. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #18 from Kenji Hara <k.hara.pg gmail.com> 2012-09-24 09:10:23 PDT --- (In reply to comment #16)Then I _definitely_ think that S() and S.init should always be the same for structs as long as static opCall has not been declaredI cannot agree with your this opinion. If S() is identical with S.init, default construction of nested struct will cause Access Violation in anywhere. It means that s1 would be broken at the example in comment#13. It is terrible language semantics. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 monarchdodra gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |monarchdodra gmail.com --- Comment #19 from monarchdodra gmail.com 2012-09-24 23:36:12 PDT --- Erm, it was my understanding that disable this() meant that it becomes illegal to initialize a struct to *just* .init (or call the .init property directly), and that a constructor must be called. The .init property still exists though, because construction can't actually happen without .init anyways... ------ import std.stdio; struct S { int i; S(int v) { i+=v; } } void main() { // S s1; //Error: variable main.main.s1 initializer required for type S S s3 = S(3); writeln(s3.i); } ------ 3 ------ The fact that this program outputs three is proof that s3 is first .init initialized, before the constructor is called proper. That's the only logical behavior (IMO) when you think of how D's initialization scheme works. If .init was truly disabled, the ONLY legal initialization would become: ---- S s = void; ---- THIS works though :/ ??? -------- void main() { S s2 = S(); //WHAT...? S s3 = S(3); writeln(s3.i); } -------- I side with Jonathan that S() and .init should be the same thing. There are no "default constructors" (or "no-arg", to my great dismay), in D, so having "S s = S();" do some things behind the scenes that "S s;" doesn't is just not conceivable from a language standpoint. The fact that the stack pointer is not known at compile time in .init (I think, anyways) should not prevent "S s;" from properly initialized, be it by a stwo-step scheme if needed. That is a compiler implementation details, and users should (NEED) to remain blissfully unaware of it. Either that, or we allow a true constructor that takes no argument: S s; // .init S s = S(); // this(){...} But as of right now, it would seem there is a bastard of an hybrid that is half of both. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 --- Comment #20 from github-bugzilla puremagic.com 2012-10-11 09:17:23 PDT --- Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/572b28e157c534bcbe918e11f9a52c7c6aa1379e fix Issue 7021 - Structs with disabled default constructors can be constructed without calling a constructor. https://github.com/D-Programming-Language/dmd/commit/3038cf1a60e07dfae3976aa7f0f2e0d17aef47d1 Merge pull request #1132 from 9rnsr/fix8703 Issue 7021 - Structs with disabled default constructors can be constructed without calling a constructor. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 11 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7021 yebblies <yebblies gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |yebblies gmail.com Resolution| |FIXED -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 28 2012