digitalmars.D.learn - This is bug or not? (immutable class containing struct with dtor)
- Denis Feklushkin (31/31) Dec 17 2021 ```d
- Denis Feklushkin (3/6) Dec 17 2021 ("serializer_bug" is just name of my local .d file)
- Tejas (20/26) Dec 17 2021 I think since `immutable` objects are kept in Read Only Storage,
- Tejas (3/30) Dec 17 2021 Correction:
- Denis Feklushkin (26/26) Dec 17 2021 On Friday, 17 December 2021 at 18:02:52 UTC, Tejas wrote:
- Tejas (7/33) Dec 17 2021 Nope, seems to go against the very promise it's making
- Denis Feklushkin (3/4) Dec 17 2021 Some of them can be stored in ROM in some cases, but actually
- Tejas (10/14) Dec 17 2021 Well, it would be really weird if destructors successfully
- =?UTF-8?Q?Ali_=c3=87ehreli?= (50/62) Dec 17 2021 Destructor is nothing but a piece of code that is executed when an
- Tejas (15/20) Dec 17 2021 Well, I got completely mislead by my experiment π
- Denis Feklushkin (11/18) Dec 18 2021 Interesting what discussed behaviour isn't affects method what
- Tejas (5/24) Dec 18 2021 As Ali said, this is an implementation issue.
- Denis Feklushkin (3/6) Dec 18 2021 Looks like this is same case:
```d /+ dub.json: { "name": "test", "dependencies": { } } +/ struct S { ~this() {} } immutable class Imm { S s; // this is immutable value because whole class is immutable this() { s = S(); } ~this() {} // Comment out this to fix this compilation error: // Error: `immutable` method `serializer_bug.Imm.~this` is not callable using a mutable object // What mutable object is meant here? } void main() { auto ic = new immutable Imm(); } ``` Run: $ dub --single bug.d
Dec 17 2021
On Friday, 17 December 2021 at 17:27:53 UTC, Denis Feklushkin wrote:~this() {} // Comment out this to fix this compilation error: // Error: `immutable` method `serializer_bug.Imm.~this` is("serializer_bug" is just name of my local .d file)
Dec 17 2021
On Friday, 17 December 2021 at 17:34:05 UTC, Denis Feklushkin wrote:On Friday, 17 December 2021 at 17:27:53 UTC, Denis Feklushkin wrote:I think since `immutable` objects are kept in Read Only Storage, you can't call destructors on them since the objects don't get erased when `~this` is called, but rather they get assigned their `.init` value, which tells the GC that they can be collected. `immutable class` has nothing to do with it, even the following fails to compile: ```d struct S { ~this() immutable {} } void main() { S s = S(); } Error: `immutable` method `onlineapp.S.~this` is not callable using a mutable object ```~this() {} // Comment out this to fix this compilation error: // Error: `immutable` method `serializer_bug.Imm.~this` is("serializer_bug" is just name of my local .d file)
Dec 17 2021
On Friday, 17 December 2021 at 18:01:03 UTC, Tejas wrote:On Friday, 17 December 2021 at 17:34:05 UTC, Denis Feklushkin wrote:Correction: `immutable S s = S();` inside the `void main()`On Friday, 17 December 2021 at 17:27:53 UTC, Denis Feklushkin wrote:I think since `immutable` objects are kept in Read Only Storage, you can't call destructors on them since the objects don't get erased when `~this` is called, but rather they get assigned their `.init` value, which tells the GC that they can be collected. `immutable class` has nothing to do with it, even the following fails to compile: ```d struct S { ~this() immutable {} } void main() { S s = S(); } Error: `immutable` method `onlineapp.S.~this` is not callable using a mutable object ```[...]("serializer_bug" is just name of my local .d file)
Dec 17 2021
On Friday, 17 December 2021 at 18:02:52 UTC, Tejas wrote: I improved your sample: ```d immutable struct S { ~this() {} } immutable struct S2 { S sss; ~this() {} } void main() { S2 s = S2(); } ``` ``` Error: `immutable` method `serializer_bug.S.~this` is not callable using a mutable object Error: mutable method `serializer_bug.S2.~this` is not callable using a `immutable` object serializer_bug.d(17,5): Consider adding `const` or `inout` here ``` immutable dtor can't be called at all?
Dec 17 2021
On Friday, 17 December 2021 at 18:32:43 UTC, Denis Feklushkin wrote:On Friday, 17 December 2021 at 18:02:52 UTC, Tejas wrote: I improved your sample: ```d immutable struct S { ~this() {} } immutable struct S2 { S sss; ~this() {} } void main() { S2 s = S2(); } ``` ``` Error: `immutable` method `serializer_bug.S.~this` is not callable using a mutable object Error: mutable method `serializer_bug.S2.~this` is not callable using a `immutable` object serializer_bug.d(17,5): Consider adding `const` or `inout` here ``` immutable dtor can't be called at all?Nope, seems to go against the very promise it's making Labelling `~this()` as const or immutable means it won't affect the state of the object, but it will, by it's very nature. That's why I said it's not too much of a stretch to imagine why they're disallowed entirely.
Dec 17 2021
On Friday, 17 December 2021 at 18:01:03 UTC, Tejas wrote:I think since `immutable` objects are kept in Read Only StorageSome of them can be stored in ROM in some cases, but actually "immutable" keyword means "not mutable for whole its lifetime"
Dec 17 2021
On Friday, 17 December 2021 at 18:19:34 UTC, Denis Feklushkin wrote:On Friday, 17 December 2021 at 18:01:03 UTC, Tejas wrote:Well, it would be really weird if destructors successfully executed for some class of `immutable` qualified objects but didn't for others. Not too much of a stretch to imagine that destruction for immutable objects was outright disallowed. Someone who can explain this behaviour more thoroughly would be much appreciated π Maybe we should allow finalizers to mutate their instance?I think since `immutable` objects are kept in Read Only StorageSome of them can be stored in ROM in some cases, but actually "immutable" keyword means "not mutable for whole its lifetime"
Dec 17 2021
On 12/17/21 10:01 AM, Tejas wrote:I think since `immutable` objects are kept in Read Only Storage,There is no such requirement nor guarantee.you can't call destructors on themDestructor is nothing but a piece of code that is executed when an object's life ends. A destructor need not touch any member of the object: struct S { ~this() { import std.stdio; writeln("done"); } } void main() { immutable a = S(); auto b = immutable(S)(); } Both objects are immutable there yet their destructor is executed.since the objects don't get erased when `~this` is called, but rather they get assigned their `.init` value,That's true only for destroy(), which gets called only if the programmer asks for it. Otherwise, destroyed objects don't get assigned any special value.which tells the GC that they can be collected.That's not true. The GC collects objects when there are no references to them. The values of the object's members have nothing to do with it.`immutable class` has nothing to do with it, even the following fails to compile: ```d struct S { ~this() immutable {}That immutable qualifier means "this destructor is for immutable objects of this type." However, it seems impossible to define two destructors: ~this() { writeln(__FUNCTION__); } ~this() immutable { writeln(__FUNCTION__); } Error: destructor `deneme.S.~this` conflicts with destructor `deneme.S.~this` at deneme.d(79) I think this is an unexplored corner of the language. Part of the complication may be due to implementations by an earlier compiler contributor, who I heard was responsible for qualifiers on constructors. Note two different constructors here: import std.stdio; struct S { this(int) { writeln(__PRETTY_FUNCTION__); } this(int) immutable { writeln(__PRETTY_FUNCTION__); } } void main() { auto a = immutable(S)(0); auto b = S(1); } I bet the problem here is that the implementation in the compiler is half-baked on these qualifiers. Ali
Dec 17 2021
On Friday, 17 December 2021 at 18:51:56 UTC, Ali Γehreli wrote:On 12/17/21 10:01 AM, Tejas wrote:Well, I got completely mislead by my experiment π ```d struct S { ~this() immutable {} } void main() { immutable S s = S(); } ``` This failed, so I just came up with reasons to justify this behaviour Thanks for correcting me π[...]Storage, There is no such requirement nor guarantee. [...]
Dec 17 2021
On Friday, 17 December 2021 at 19:03:05 UTC, Tejas wrote:Well, I got completely mislead by my experiment π ```d struct S { ~this() immutable {} } ```Interesting what discussed behaviour isn't affects method what implements same functionality as dtor and called explictly at each appropriate place. So for dirty fix I just created ```d void __custom_dtor() const { ... } ``` And then called this __custom_dtor at each dtor what uses this struct.
Dec 18 2021
On Saturday, 18 December 2021 at 11:01:53 UTC, Denis Feklushkin wrote:On Friday, 17 December 2021 at 19:03:05 UTC, Tejas wrote:As Ali said, this is an implementation issue. So I guess the answer to your question is that this is a bug. Please file a report at [issues.dlang.org](issues.dlang.org)Well, I got completely mislead by my experiment π ```d struct S { ~this() immutable {} } ```Interesting what discussed behaviour isn't affects method what implements same functionality as dtor and called explictly at each appropriate place. So for dirty fix I just created ```d void __custom_dtor() const { ... } ``` And then called this __custom_dtor at each dtor what uses this struct.
Dec 18 2021
On Saturday, 18 December 2021 at 12:50:17 UTC, Tejas wrote:As Ali said, this is an implementation issue. So I guess the answer to your question is that this is a bug. Please file a report at [issues.dlang.org](issues.dlang.org)Looks like this is same case: https://issues.dlang.org/show_bug.cgi?id=13628
Dec 18 2021