Re: Make sure lifetime of helper structs is less than owning struct

2021-11-16 Thread Ali Çehreli via Digitalmars-d-learn

On 11/16/21 12:35 AM, Sebastiaan Koppe wrote:

> Here the
> OP wanted to (have the compiler) destroy the FileReader when it left the
> scope, while disallowing any use after free.

Thanks! That's what I missed.

Ali



Re: Make sure lifetime of helper structs is less than owning struct

2021-11-16 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Monday, 15 November 2021 at 22:49:12 UTC, Ali Çehreli wrote:

Trying with it produces an error when 'new' is not used:

Error: reference to local variable `file` assigned to non-scope 
parameter `p` calling deneme.ByChunk.opAssign


The error is what the OP wanted, so that is expected.

Although, he did ask for it to be on the next line, but this is 
better since it points exactly to the line where he was escaping 
a reference to the scoped object.


I don't see how it solves the problem. Sebastiaan Koppe might 
have intended to allocate the object dynamically with 'new' as 
well?


No I didn't. Anything created with new has automatic lifetime. 
Here the OP wanted to (have the compiler) destroy the FileReader 
when it left the scope, while disallowing any use after free.


Re: Make sure lifetime of helper structs is less than owning struct

2021-11-15 Thread Ali Çehreli via Digitalmars-d-learn

On 11/15/21 2:33 PM, Imperatorn wrote:

On Monday, 15 November 2021 at 22:27:24 UTC, Ali Çehreli wrote:

On 11/15/21 1:58 PM, WebFreak001 wrote:
> [...]
wrote:
>> [...]
wrote:
>> [...]
the use of
>> [...]
variable `file`
> [...]
copying the
> [...]
a pointer.
I don't see how it solves the problem. Sebastiaan Koppe might have 
intended to allocate the object dynamically with 'new' as well?


[...]


Are you compiling with preview=dip1000?


Trying with it produces an error when 'new' is not used:

Error: reference to local variable `file` assigned to non-scope 
parameter `p` calling deneme.ByChunk.opAssign


So, I either misunderstand or understand very well :) that a different 
way of lifetime management (like adding 'new') is needed there.


Ali



Re: Make sure lifetime of helper structs is less than owning struct

2021-11-15 Thread Imperatorn via Digitalmars-d-learn

On Monday, 15 November 2021 at 22:27:24 UTC, Ali Çehreli wrote:

On 11/15/21 1:58 PM, WebFreak001 wrote:
> [...]
wrote:
>> [...]
wrote:
>> [...]
the use of
>> [...]
variable `file`
> [...]
copying the
> [...]
a pointer.
I don't see how it solves the problem. Sebastiaan Koppe might 
have intended to allocate the object dynamically with 'new' as 
well?


[...]


Are you compiling with preview=dip1000?


Re: Make sure lifetime of helper structs is less than owning struct

2021-11-15 Thread Ali Çehreli via Digitalmars-d-learn

On 11/15/21 1:58 PM, WebFreak001 wrote:
> On Monday, 15 November 2021 at 19:24:56 UTC, Sebastiaan Koppe wrote:
>> On Monday, 15 November 2021 at 15:56:57 UTC, WebFreak001 wrote:
>>> is this currently possible or maybe possible with DIP1000?
>>
>> Yes it is. But besides `-dip1000` and `@safe`, it requires the use of
>> a pointer:
>>
>> ```D
>> @safe:
>>
>> struct ByChunk {
>> FileReader* r;
>> void popFront() {}
>> }
>>
>> struct FileReader {
>> ByChunk byChunk() return scope {
>> return ByChunk();
>> }
>> }
>>
>> void main() {
>> ByChunk helper;
>> {
>>auto file = FileReader();
>> helper = file.byChunk;  // Error: address of variable `file`
>> assigned to `helper` with longer lifetime
>> }
>> helper.popFront;
>> }
>> ```
>
> awesome, such a simple solution! Also saves me the pain of copying the
> struct data and avoiding copy constructor and stuff by using a pointer.
I don't see how it solves the problem. Sebastiaan Koppe might have 
intended to allocate the object dynamically with 'new' as well?


import std.stdio;

@safe:

struct ByChunk {
  FileReader* r;

  ~this() {
writeln(__FUNCTION__);
  }

  void popFront() {
writeln("popFront on ", r);
  }
}

struct FileReader {
  ~this() {
writeln(__FUNCTION__, " on ", );
  }

  ByChunk byChunk() return scope {
return ByChunk();
  }
}

void main() {
  ByChunk helper;
  {
auto file = new FileReader();  // <-- NOTE new
helper = file.byChunk;
  }
  writeln("back in main");
  helper.popFront;
}

This is the current output:

deneme.ByChunk.~this
back in main
popFront on 7F12B377E000
deneme.ByChunk.~this
deneme.FileReader.~this on 7F12B377E000

But without that 'new', FileReader is destroyed before popFront:

deneme.ByChunk.~this
deneme.FileReader.~this on 7FFD8231D4B8   <-- BAD
back in main
popFront on 7FFD8231D4B8
deneme.ByChunk.~this

I think I am misunderstanding something here. :)

Ali



Re: Make sure lifetime of helper structs is less than owning struct

2021-11-15 Thread Imperatorn via Digitalmars-d-learn
On Monday, 15 November 2021 at 19:24:56 UTC, Sebastiaan Koppe 
wrote:

On Monday, 15 November 2021 at 15:56:57 UTC, WebFreak001 wrote:

is this currently possible or maybe possible with DIP1000?


Yes it is. But besides `-dip1000` and `@safe`, it requires the 
use of a pointer:


```D
@safe:

struct ByChunk {
FileReader* r;
void popFront() {}
}

struct FileReader {
ByChunk byChunk() return scope {
return ByChunk();
}
}

void main() {
ByChunk helper;
{
auto file = FileReader();
	helper = file.byChunk;  // Error: address of variable 
`file` assigned to `helper` with longer lifetime

}
helper.popFront;
}
```


Maybe a candidate for the "d idioms" page


Re: Make sure lifetime of helper structs is less than owning struct

2021-11-15 Thread WebFreak001 via Digitalmars-d-learn
On Monday, 15 November 2021 at 19:24:56 UTC, Sebastiaan Koppe 
wrote:

On Monday, 15 November 2021 at 15:56:57 UTC, WebFreak001 wrote:

is this currently possible or maybe possible with DIP1000?


Yes it is. But besides `-dip1000` and `@safe`, it requires the 
use of a pointer:


```D
@safe:

struct ByChunk {
FileReader* r;
void popFront() {}
}

struct FileReader {
ByChunk byChunk() return scope {
return ByChunk();
}
}

void main() {
ByChunk helper;
{
auto file = FileReader();
	helper = file.byChunk;  // Error: address of variable 
`file` assigned to `helper` with longer lifetime

}
helper.popFront;
}
```


awesome, such a simple solution! Also saves me the pain of 
copying the struct data and avoiding copy constructor and stuff 
by using a pointer.


Re: Make sure lifetime of helper structs is less than owning struct

2021-11-15 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Monday, 15 November 2021 at 15:56:57 UTC, WebFreak001 wrote:

is this currently possible or maybe possible with DIP1000?


Yes it is. But besides `-dip1000` and `@safe`, it requires the 
use of a pointer:


```D
@safe:

struct ByChunk {
FileReader* r;
void popFront() {}
}

struct FileReader {
ByChunk byChunk() return scope {
return ByChunk();
}
}

void main() {
ByChunk helper;
{
auto file = FileReader();
	helper = file.byChunk;  // Error: address of variable `file` 
assigned to `helper` with longer lifetime

}
helper.popFront;
}
```


Re: Make sure lifetime of helper structs is less than owning struct

2021-11-15 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Nov 15, 2021 at 03:56:57PM +, WebFreak001 via Digitalmars-d-learn 
wrote:
> I have an API with some struct like a file reader. I want to add
> byChunks-like functionality to it, so I'm trying to implement it with
> a helper struct that implements opApply. I have disabled copying the
> file reader struct because it cleans up the resources once it goes out
> of scope, however now I need to temporarily save the resources in the
> helper struct to be able to read from it.
> 
> How can I make sure that the foreach helper struct (and with that the
> copies of the resources) cannot be used once the owning struct goes
> out of scope?
> 
> ```d
> ByChunk helper;
> {
> auto file = FileReader(x);
> helper = file.byChunk;
> }
> helper.popFront; // crash - I want the compiler to disallow this
> ```
> 
> is this currently possible or maybe possible with DIP1000?

What about make ByChunk do the construction of the File in its ctor
instead?  The problem with constructing it separately is that you can't
tie the two lifetimes together.  But if you create the File while
initializing the object, you ensure that the two lifetimes are tied
together, and with @disable this() you can make sure that ByChunk is not
constructible unless the code that opens the File also runs.


T

-- 
Computers shouldn't beep through the keyhole.


Re: Make sure lifetime of helper structs is less than owning struct

2021-11-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/15/21 10:56 AM, WebFreak001 wrote:
I have an API with some struct like a file reader. I want to add 
byChunks-like functionality to it, so I'm trying to implement it with a 
helper struct that implements opApply. I have disabled copying the file 
reader struct because it cleans up the resources once it goes out of 
scope, however now I need to temporarily save the resources in the 
helper struct to be able to read from it.


How can I make sure that the foreach helper struct (and with that the 
copies of the resources) cannot be used once the owning struct goes out 
of scope?


```d
ByChunk helper;
{
     auto file = FileReader(x);
     helper = file.byChunk;
}
helper.popFront; // crash - I want the compiler to disallow this
```

is this currently possible or maybe possible with DIP1000?


Or maybe just use reference counting to avoid the problem altogether. 
That's what iopipe/std.io does.


-Steve