www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Disabling struct destructor illegal?

reply RazvanN <razvan.nitu1305 gmail.com> writes:
struct A
{
     int a;
      disable ~this() {}
}

void main()
{
     A a = A(2);
}

Currently, this code yields:

Error: destructor `A.~this` cannot be used because it is 
annotated with  disable

I was expecting that disabling the destructor would make it as if 
the struct does not have a destructor, instead it makes the 
program not compile. I find this behavior odd: why not make it 
illegal to disable the destructor if disabling it will surely 
result in errors wherever the struct is used. The only situation 
where the code will compile is A is never used directly. To make 
matters even more confusing, this code compiles:

class A
{
     int a;
      disable ~this() {}
}

void main()
{
     A a = new A();
}


So, is this a bug or am I missing something?

Yoroshiku onegaishimasu,
RazvanN
Jul 19 2018
next sibling parent reply Jim Balter <Jim Balter.name> writes:
On Thursday, 19 July 2018 at 08:50:15 UTC, RazvanN wrote:
 struct A
 {
     int a;
      disable ~this() {}
 }

 void main()
 {
     A a = A(2);
 }

 Currently, this code yields:

 Error: destructor `A.~this` cannot be used because it is 
 annotated with  disable

 I was expecting that disabling the destructor would make it as 
 if the struct does not have a destructor
Why? That's not the semantics of disable. And why would you want that? What are you actually trying to achieve?
 , instead it makes the program not compile. I find this 
 behavior odd: why not make it illegal to disable the destructor 
 if disabling it will surely result in errors wherever the 
 struct is used.
Because it won't surely result in errors wherever the struct is used ... you yourself provide an example below where it doesn't. The only
 situation where the code will compile is A is never used 
 directly.
Eh? You immediately give a contrary example:
 To make matters even more confusing, this code compiles:

 class A
 {
     int a;
      disable ~this() {}
 }

 void main()
 {
     A a = new A();
 }
Why is that confusing? Why shouldn't it compile? The A that you created is on the heap, so its destructor is never invoked, so what would cause it not to compile?
 So, is this a bug or am I missing something?

 Yoroshiku onegaishimasu,
 RazvanN
Jul 19 2018
parent reply RazvanN <razvan.nitu1305 gmail.com> writes:
On Thursday, 19 July 2018 at 09:50:32 UTC, Jim Balter wrote:
 On Thursday, 19 July 2018 at 08:50:15 UTC, RazvanN wrote:
 struct A
 {
     int a;
      disable ~this() {}
 }

 void main()
 {
     A a = A(2);
 }

 Currently, this code yields:

 Error: destructor `A.~this` cannot be used because it is 
 annotated with  disable

 I was expecting that disabling the destructor would make it as 
 if the struct does not have a destructor
Why? That's not the semantics of disable. And why would you want that? What are you actually trying to achieve?
I just don't understand why you would ever mark the destructor of a struct with disable. When is that useful? If it's not, why not just forbit it?
Jul 19 2018
next sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Thursday, 19 July 2018 at 10:04:34 UTC, RazvanN wrote:
 I just don't understand why you would ever mark the destructor 
 of a struct with  disable. When is that useful? If it's not, 
 why not just forbit it?
struct S1 { ~this() { /* stuff */ } } struct S2 { S1 s; disable ~this(); } The idea would be that S1's destructor not be called when S2 goes out of scope. Now, that's not how disable works, but it's a logical thought. The way disable does work though, isn't to remove the marked function, but forbid it from being called.
 why not make it illegal to disable the destructor if disabling 
 it will surely result in errors wherever the struct is used.
Because the error message when you use it clearly states what's wrong? It's actually possible to use a struct with a disabled destructor: struct S { int i; disable ~this() {} } struct Nodestruct(T) { ubyte[T.sizeof] _payload; property ref T value() { return *cast(T*)_payload.ptr; } } The trick is, as you can see, to never have an instance on the stack. This gives a small advantage over disable this(this) and disable this() in that it's actually impossible to have a stack-allocated instance. -- Simen
Jul 19 2018
prev sibling next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, July 19, 2018 10:04:34 RazvanN via Digitalmars-d-learn wrote:
 I just don't understand why you would ever mark the destructor of
 a struct with  disable. When is that useful? If it's not, why not
 just forbit it?
There's nothing special about destructors here. You can disable any member function, and if you do, you get an error if you try to use it, since it's disabled. So, code that doesn't use an disabled function works just fine, and any code that attempts to use it gets an error. For the vast majority of functions, disabling them really doesn't make any sense, but from what I can tell, disable was simply implemented as a general feature rather than trying to allow specific functions to be disabled and then have to add code for each function that we want to be able to disable. So, the fact that you can disable destructors is just the result of the feature being implemented in a simple, straightforward manner. But while I agree that disabling destructors doesn't make sense, I don't see why it would actually be a problem that it's allowed. Anyone who tries it is just going to quickly get errors and have to remove disable from the destructor. Explicitly make it illegal to mark a destructor with disabled doesn't really add anything from what I can see. - Jonathan M Davis
Jul 19 2018
prev sibling parent Jim Balter <Jim Balter.name> writes:
On Thursday, 19 July 2018 at 10:04:34 UTC, RazvanN wrote:
 On Thursday, 19 July 2018 at 09:50:32 UTC, Jim Balter wrote:
 On Thursday, 19 July 2018 at 08:50:15 UTC, RazvanN wrote:
 struct A
 {
     int a;
      disable ~this() {}
 }

 void main()
 {
     A a = A(2);
 }

 Currently, this code yields:

 Error: destructor `A.~this` cannot be used because it is 
 annotated with  disable

 I was expecting that disabling the destructor would make it 
 as if the struct does not have a destructor
Why? That's not the semantics of disable. And why would you want that? What are you actually trying to achieve?
I just don't understand why you would ever mark the destructor of a struct with disable. When is that useful?
I don't know, but that doesn't mean there's no possible reason to.
 If it's not,
We haven't established that it's never useful. When you pose a conditional like that, it's a logical mistake to just assume that the condition is met.
 why not just forbit it?
Because the compiler shouldn't be littered with pointless special case restrictions that have to be maintained and might interfere with a valid use case that you haven't thought of. The fact is that you disabled the destructor, then invoked the destructor, and got a clear, informative error at the point of invocation, rather than at the disable. This is, IMO, a cleaner, better design than the one you're asking for. And it's not true that you "just" don't understand why one would ever disable the destructor ... in your original post you asked "why not make it illegal to disable the destructor if disabling it will surely result in errors wherever the struct is used" -- it was pointed out that it *doesn't* "surely result in errors wherever the struct is used" -- it only results in an error if the destructor is invoked, exactly as one would expect. In your original post you claimed "The only situation where the code will compile is A is never used directly" -- it was pointed out that this isn't true, as your own example showed. In your original post you said that it was confusing that code that you had just erroneously stated wouldn't compile does compile, and it was pointed out that there's no reason why it shouldn't compile and there's no apparent reason to find it confusing. In your original post you asked if that's a bug, and it has been pointed out that it's not a bug. I hope everything is clear now and all your questions have been answered.
Jul 20 2018
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 7/19/18 4:50 AM, RazvanN wrote:
 struct A
 {
      int a;
       disable ~this() {}
 }
 
 void main()
 {
      A a = A(2);
 }
 
 Currently, this code yields:
 
 Error: destructor `A.~this` cannot be used because it is annotated with 
  disable
 
 I was expecting that disabling the destructor would make it as if the 
 struct does not have a destructor, instead it makes the program not 
 compile.
That's a misunderstanding of disable. disable *defines* the function, and makes it uncallable. If you want a struct without a destructor, just don't define one. Or if you want one that eliminates the default destructor (in the case where you have members with dtors), define an empty destrutor. -Steve
Jul 20 2018