November 10, 2021

On Tuesday, 9 November 2021 at 17:04:29 UTC, Paul Backus wrote:

>

Here's a basic sketch of the scheme I had in mind: https://gist.github.com/run-dlang/d1982a29423b2cb545bc9fa452d94c5e

It's entirely possible I've overlooked something and this is actually unsound. As Andrei says: "destroy!"

There are a few problems with the code, indeed.
1/ You need to add runtime check, because in D, destructed objects may not have been constructed, so you need to be able to destroy .init . in your case, pointers will be null and you'll segfault.
2/ For a struct, you cannot guarantee that the struct's method don't escape the struct pointer, so none of this can be safe in any way.

November 10, 2021

On Tuesday, 9 November 2021 at 18:33:01 UTC, Atila Neves wrote:

>

I think that C++'s greatest gift to the world was the destructor. We have those too! Let's use them.

Indeed, but I have unfortunate news. We broke the gift. In D, object can be destroyed without being constructed first.

Consider: https://godbolt.org/z/EdW75jWGn

This is the first problem we need to fix here, if we don't want to have to plaster our code with runtime checks.

November 10, 2021

On Tuesday, 9 November 2021 at 18:33:01 UTC, Atila Neves wrote:

>

On Tuesday, 9 November 2021 at 17:26:32 UTC, Stanislav Blinov wrote:

>

[...]

Could you please explain why you'd rather do that instead of using the equivalent of C++'s std::{vector, unique_ptr, shared_ptr} and Rust's std::{vector, unique_ptr, shared_ptr}? I cannot myself imagine why anyone would want to.

I think that C++'s greatest gift to the world was the destructor. We have those too! Let's use them.

Actually that honour belongs to Euclid, C++ made it popular.

November 10, 2021

On Wednesday, 10 November 2021 at 13:52:26 UTC, deadalnix wrote:

>

On Tuesday, 9 November 2021 at 18:33:01 UTC, Atila Neves wrote:

>

I think that C++'s greatest gift to the world was the destructor. We have those too! Let's use them.

Indeed, but I have unfortunate news. We broke the gift. In D, object can be destroyed without being constructed first.

Consider: https://godbolt.org/z/EdW75jWGn

This is the first problem we need to fix here, if we don't want to have to plaster our code with runtime checks.

The struct is instantiated [1], it just doesn't run the constructor in that case. You can always disable the default constructor. Doesn't C++ have an implicit default constructor also?

[1] https://dlang.org/spec/struct.html#struct-instantiation

November 10, 2021

On Wednesday, 10 November 2021 at 13:48:53 UTC, deadalnix wrote:

>

On Tuesday, 9 November 2021 at 17:04:29 UTC, Paul Backus wrote:

>

Here's a basic sketch of the scheme I had in mind: https://gist.github.com/run-dlang/d1982a29423b2cb545bc9fa452d94c5e

It's entirely possible I've overlooked something and this is actually unsound. As Andrei says: "destroy!"

There are a few problems with the code, indeed.
1/ You need to add runtime check, because in D, destructed objects may not have been constructed, so you need to be able to destroy .init . in your case, pointers will be null and you'll segfault.

Destroying .init works fine here. free(null) is guaranteed by the C standard to be a no-op.

>

2/ For a struct, you cannot guarantee that the struct's method don't escape the struct pointer, so none of this can be safe in any way.

Good point. I guess you'd need transitive scope for this, at minimum.

November 10, 2021
On Wed, Nov 10, 2021 at 01:52:26PM +0000, deadalnix via Digitalmars-d wrote:
> On Tuesday, 9 November 2021 at 18:33:01 UTC, Atila Neves wrote:
> > I think that C++'s greatest gift to the world was the destructor. We have those too! Let's use them.
> > 
> 
> Indeed, but I have unfortunate news. We broke the gift. In D, object can be destroyed without being constructed first.
> 
> Consider: https://godbolt.org/z/EdW75jWGn
> 
> This is the first problem we need to fix here, if we don't want to have to plaster our code with runtime checks.

Isn't that what @disable this() is for?

And to be pedantic, the object *was* constructed -- by the default ctor. If you didn't want that, you should @disable this().


T

-- 
"The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." -- Bertrand Russell. "How come he didn't put 'I think' at the end of it?" -- Anonymous
November 10, 2021
On Wednesday, 10 November 2021 at 17:09:05 UTC, H. S. Teoh wrote:
> Isn't that what @disable this() is for?
>
> And to be pedantic, the object *was* constructed -- by the default ctor. If you didn't want that, you should @disable this().
>
>
> T

No.

Everything that is destructed must have been constructed. It is the only way you can enforce invariant within a type.
November 10, 2021

On Wednesday, 10 November 2021 at 14:04:18 UTC, jmh530 wrote:

>

The struct is instantiated [1], it just doesn't run the constructor in that case. You can always disable the default constructor. Doesn't C++ have an implicit default constructor also?

D does not allow a default constructor all… that is weird.

In C++ you get implicit constructors only if you provided no constructors at all.

November 10, 2021

On Wednesday, 10 November 2021 at 14:47:34 UTC, Paul Backus wrote:

>

Destroying .init works fine here. free(null) is guaranteed by the C standard to be a no-op.

Decrementing the reference count is going to segfault if the pointer to the owner is null.

November 10, 2021
On Wednesday, 10 November 2021 at 17:24:03 UTC, deadalnix wrote:
> On Wednesday, 10 November 2021 at 17:09:05 UTC, H. S. Teoh wrote:
>> Isn't that what @disable this() is for?
>>
>> And to be pedantic, the object *was* constructed -- by the default ctor. If you didn't want that, you should @disable this().
>>
>>
>> T
>
> No.
>
> Everything that is destructed must have been constructed. It is the only way you can enforce invariant within a type.

Invariants must hold also with structures initialised from '.init', if you don't want to @disable this()...