Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
August 28, 2016 mutable destructor? WAT??? | ||||
---|---|---|---|---|
| ||||
object.destroy doesn't want to destroy const structure with destructor: struct T { ~this() {} } void foo_t(ref T t) { destroy(t); // works } void foo_ct(ref const T t) { destroy(t); // Error: mutable method T.~this is not callable using a const object } Mutable destructor? O___o With this difinition both functions compiles: struct T { ~this() const {} // WAT??? } Is there a bug in druntime? |
August 28, 2016 Re: mutable destructor? WAT??? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Sunday, 28 August 2016 at 09:43:02 UTC, Jack Applegame wrote: > object.destroy doesn't want to destroy const structure with destructor: > [...] > Is there a bug in druntime? Yes and I believe this is https://issues.dlang.org/show_bug.cgi?id=4338 |
August 28, 2016 Re: mutable destructor? WAT??? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | Looks correct to me. This const annotation does not prevent you from deleting memory or free'ing external resources - but it does ensure no transitive mutations for data reachable from struct fields. If it allowed destroying with mutable destructor, type system hole like this would be legal: struct S { char[] str; ~this() { str[0] = 'a'; } } auto s = new const S("abcd"); destroy(s); // mutates immutable literal |
August 29, 2016 Re: mutable destructor? WAT??? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On 8/28/16 6:35 AM, Dicebot wrote:
> Looks correct to me. This const annotation does not prevent you from
> deleting memory or free'ing external resources - but it does ensure no
> transitive mutations for data reachable from struct fields. If it
> allowed destroying with mutable destructor, type system hole like this
> would be legal:
>
> struct S
> {
> char[] str;
> ~this() { str[0] = 'a'; }
> }
>
> auto s = new const S("abcd");
> destroy(s); // mutates immutable literal
void foo(const(S) str) {}
void main()
{
char[1] str = ['0'];
auto s = S(str[]);
foo(s);
writeln(str[]);
}
Clearly non-const destructors can be run on const structs (correctly or incorrectly).
Pretty positive that in your example, if you don't destroy s, the GC will call the dtor on your "const" struct.
Unsaid in the OP as well is that the given code will work if you don't define a destructor.
I'm not sure that this is necessarily a bug in the compiler, however. I don't think it should be reasonable to assume a normal function like destroy can circumvent attributes.
-Steve
|
August 29, 2016 Re: mutable destructor? WAT??? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 8/29/16 12:05 PM, Steven Schveighoffer wrote:
> On 8/28/16 6:35 AM, Dicebot wrote:
>> Looks correct to me. This const annotation does not prevent you from
>> deleting memory or free'ing external resources - but it does ensure no
>> transitive mutations for data reachable from struct fields. If it
>> allowed destroying with mutable destructor, type system hole like this
>> would be legal:
>>
>> struct S
>> {
>> char[] str;
>> ~this() { str[0] = 'a'; }
>> }
>>
>> auto s = new const S("abcd");
>> destroy(s); // mutates immutable literal
>
> void foo(const(S) str) {}
>
> void main()
> {
> char[1] str = ['0'];
> auto s = S(str[]);
> foo(s);
> writeln(str[]);
> }
Sorry if not obvious, the writeln prints "a". So the destructor was run as foo exits.
-Steve
|
August 29, 2016 Re: mutable destructor? WAT??? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | And this segfaults (on Linux): void main() @safe { auto s = const(S)("abcd"); foo(s); } I'd call it a clear bug. Most obvious fix would be to require const destructor if non-default destructor is present AND immutable/const instance is attempted to be created. |
August 29, 2016 Re: mutable destructor? WAT??? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On 8/29/16 3:00 PM, Dicebot wrote:
> And this segfaults (on Linux):
>
> void main() @safe
> {
> auto s = const(S)("abcd");
> foo(s);
> }
>
> I'd call it a clear bug. Most obvious fix would be to require const
> destructor if non-default destructor is present AND immutable/const
> instance is attempted to be created.
I think this would break a LOT of code. But it may be necessary.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation