October 07, 2015
On Wednesday, 7 October 2015 at 14:13:38 UTC, Meta wrote:
> On Wednesday, 7 October 2015 at 09:59:05 UTC, Timon Gehr wrote:
>> struct S{
>>     @disable this();
>>     @disable enum init=0;
>> }
>>
>> void main(){
>>     S s; // error
>>     auto d=S.init; // error
>> }
>
> That's just awful.

Being able to declare a member named init is just asking for trouble...

https://issues.dlang.org/show_bug.cgi?id=14237
https://issues.dlang.org/show_bug.cgi?id=7066

- Jonathan M Davis
October 07, 2015
On Wednesday, 7 October 2015 at 14:50:52 UTC, Jonathan M Davis wrote:
> Being able to declare a member named init is just asking for trouble...
>
> https://issues.dlang.org/show_bug.cgi?id=14237
> https://issues.dlang.org/show_bug.cgi?id=7066
>
> - Jonathan M Davis

Yeah, no arguments there. This needs to be properly disallowed in the compiler.
October 07, 2015
On 10/07/2015 06:52 PM, Meta wrote:
> On Wednesday, 7 October 2015 at 14:50:52 UTC, Jonathan M Davis wrote:
>> Being able to declare a member named init is just asking for trouble...
>>
>> https://issues.dlang.org/show_bug.cgi?id=14237
>> https://issues.dlang.org/show_bug.cgi?id=7066
>>
>> - Jonathan M Davis
>
> Yeah, no arguments there. This needs to be properly disallowed in the
> compiler.

The use case I have shown needs a proper migration path though.
October 07, 2015
On 10/07/2015 04:13 PM, Meta wrote:
> On Wednesday, 7 October 2015 at 09:59:05 UTC, Timon Gehr wrote:
>> struct S{
>>     @disable this();
>>     @disable enum init=0;
>> }
>>
>> void main(){
>>     S s; // error
>>     auto d=S.init; // error
>> }
>
> That's just awful.

I was responding to:

> The above shows that you cannot construct such a type in D. The
> language simply does not allow you to cancel a certain feature
> of the type in which you are uninterested.

Obviously there should be a nicer way to do this, but the above claim is simply untrue.
October 07, 2015
On Wednesday, 7 October 2015 at 18:38:34 UTC, Timon Gehr wrote:
> On 10/07/2015 04:13 PM, Meta wrote:
>> On Wednesday, 7 October 2015 at 09:59:05 UTC, Timon Gehr wrote:
>>> struct S{
>>>     @disable this();
>>>     @disable enum init=0;
>>> }
>>>
>>> void main(){
>>>     S s; // error
>>>     auto d=S.init; // error
>>> }
>>
>> That's just awful.
>
> I was responding to:

Yeah, I was just expressing my disgust that D allows this.
October 08, 2015
On 07/10/15 12:58, Timon Gehr wrote:

>> Shachar
>
> struct S{
>      @disable this();
>      @disable enum init=0;
> }
>
> void main(){
>      S s; // error
>      auto d=S.init; // error
> }
>

An honest question. Would that also cover all cases where init is being used implicitly by the compiler?

I will need to do some research myself, but my gut feeling is "no". There are several cases where the compiler replaces the value with the init value, and I doubt your horrid hack changes that.

Either way, I think you'll agree that D needs to be better in defining what is the correct path to take on this, as, currently, nobody seems to know for sure.

Shachar
October 08, 2015
On Wednesday, 7 October 2015 at 14:50:52 UTC, Jonathan M Davis wrote:
> On Wednesday, 7 October 2015 at 14:13:38 UTC, Meta wrote:
>> On Wednesday, 7 October 2015 at 09:59:05 UTC, Timon Gehr wrote:
>>> struct S{
>>>     @disable this();
>>>     @disable enum init=0;
>>> }
>>>
>>> void main(){
>>>     S s; // error
>>>     auto d=S.init; // error
>>> }
>>
>> That's just awful.
>
> Being able to declare a member named init is just asking for trouble...
>
> https://issues.dlang.org/show_bug.cgi?id=14237
> https://issues.dlang.org/show_bug.cgi?id=7066
>
> - Jonathan M Davis

https://issues.dlang.org/show_bug.cgi?id=12233 is also related and incredibly bug-prone.
October 08, 2015
Am Mon, 05 Oct 2015 13:42:50 +0000
schrieb Adam D. Ruppe <destructionator@gmail.com>:

> On Monday, 5 October 2015 at 07:40:35 UTC, deadalnix wrote:
> > Not on the heap. There are many cases where the destructor won't run and it is allowed by spec. We should do better.
> 
> To be fair, if you new a struct in C++ and never delete it, the destructor will never run there either. D's in the same boat in that regard.

But the D boat reads "Garbage Collector". And besides, D now runs dtors on new'd structs. The "many cases" may be different ones than you imagine.

-- 
Marco

October 08, 2015
Am Mon, 5 Oct 2015 12:22:59 +0300
schrieb Shachar Shemesh <shachar@weka.io>:

> On 05/10/15 10:01, Dmitry Olshansky wrote:
> 
> >> When D structs has a destructor that is guaranteed to run for any instance that finished construction, no matter what is the use case, then we can have that discussion.
> >>
> >
> > Supposed to be the case for structs except for any bugs.
> >
> 
> Check this one out (no instances on heap):
> import std.stdio;
> 
> struct destructible {
>      int id;
> 
>      @disable this();
>      this( int id ) {
>          writeln("Id ", id, " constructed");
>          this.id = id;
>      }
> 
>      ~this() {
>          writeln("Id ", id, " destructed");
>      }
> }
> 
> void main() {
>      struct container {
>          destructible d;
> 
>          @disable this();
>          this( int id )
>          {
>              this.d = destructible(id);
>              throw new Exception("some random exception");
>          }
>      }
> 
>      try {
>          container(2);
>      } catch( Exception ex ) {
>          writeln("Caught ", ex.msg);
>      }
> }
> 
> As of dmd 2.068.2, the output is:
> Id 2 constructed
> Caught Some random exception
> 
> Of course, if I do not disable this(), things are even worse.

Damn this is sneaky! Now the statements

"When D structs has a destructor that is guaranteed to run for any instance that finished construction."

"When construction fails, the dtor is not run on that half-constructed object. Instead it is the ctors responsibility to roll back its actions."

collide with a struct that finished construction embedded in a struct that failed construction. This is a deadlock.

-- 
Marco

October 08, 2015
On Thursday, 8 October 2015 at 15:58:37 UTC, Marco Leise wrote:
> Am Mon, 05 Oct 2015 13:42:50 +0000
> schrieb Adam D. Ruppe <destructionator@gmail.com>:
>
>> On Monday, 5 October 2015 at 07:40:35 UTC, deadalnix wrote:
>> > Not on the heap. There are many cases where the destructor won't run and it is allowed by spec. We should do better.
>> 
>> To be fair, if you new a struct in C++ and never delete it, the destructor will never run there either. D's in the same boat in that regard.
>
> But the D boat reads "Garbage Collector". And besides, D now runs dtors on new'd structs. The "many cases" may be different ones than you imagine.

It's still the case though that if the GC does not collect a struct on the GC heap, its destructor is not going to be run. And there's no guarantee that _anything_ on the GC heap will ever be collected. That depends on stuff like the memory usage of the program. We're better off than we were, because when a struct on the GC heap is collected, it's destructor will now be run, whereas it wouldn't have been before, but ultimately, it's still the same boat as C++ with regards to structs that never get collected. It's just that in C++, you don't usually let memory leak like that, whereas a GC doesn't normally collect everything when the program shuts down. So, you're unlikely to run into a case in C++ where a struct never gets destroyed, whereas it's pretty easy in D.

- Jonathan M Davis