Re: pointer escaping return scope bug?

2022-11-25 Thread Tejas via Digitalmars-d-learn

On Friday, 25 November 2022 at 17:45:57 UTC, Paul Backus wrote:

On Friday, 25 November 2022 at 14:07:28 UTC, ShadoLight wrote:
On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus 
wrote:
Since, in your example, `lf` has global lifetime, the 
compiler deduces that `lf.fp` also has global lifetime, and 
therefore there is nothing wrong with assigning it to `p`.


I follow your rationale, but for the life of me I cannot see 
how `lf` _"has global lifetime"_.


You're right, my terminology here is sloppy. I'm really talking 
about the memory pointed to by `lf`, not `lf` itself, so I 
should really say that `lf` *points to memory* with global 
lifetime (or perhaps "`*lf` has global lifetime").


Time to use separation logic

# 


Re: "Little Scheme" and PL Design (Code Critique?)

2022-11-25 Thread jwatson-CO-edu via Digitalmars-d-learn

On Tuesday, 22 November 2022 at 08:19:44 UTC, JG wrote:
On Thursday, 17 November 2022 at 22:05:45 UTC, jwatson-CO-edu 
wrote:
I just pushed a D implementation of "[Little 
Scheme](https://mitpress.mit.edu/9780262560993/the-little-schemer/)", which is a limited educational version of [Scheme](https://en.wikipedia.org/wiki/Scheme_(programming_language)), to [GitHub](https://github.com/jwatson-CO-edu/SPARROW).


[...]


I think using the d garbage collector is a good idea. (I have 
written two implementations of scheme like languages one in c 
and one in d, and I found it a great pleasure not to have to 
write a GC for the d one). On the other hand if you want to 
write one there is no obstruction doing so in d.


Have you put your Schemes up on GitHub?  What are the biggest 
lessons you learned from writing them?


Yes, allowing D GC to do its thing is my course for the time 
being.  In the near future I want to test starting the 
interpreter with a block of variable memory allocated to see if 
this reduces cache misses at runtime. The results of this test 
will determine if, and the degree to which, I will fiddle with GC.


Re: "Little Scheme" and PL Design (Code Critique?)

2022-11-25 Thread jwatson-CO-edu via Digitalmars-d-learn

On Monday, 21 November 2022 at 14:36:43 UTC, Paul Backus wrote:
On Thursday, 17 November 2022 at 22:05:45 UTC, jwatson-CO-edu 
wrote:
* Compatibility with both Windows and Linux. What do I need to 
consider?

  - Can I create threads/processes under Windows?


[core.thread][1] and [std.process][2] provide 
platform-independent interfaces for this that should work on 
both Windows and Linux.


[1]: https://druntime.dpldocs.info/core.thread.html
[2]: https://phobos.dpldocs.info/std.process.html


Splendid! High praise to the contributors that were able to do 
this on multiple platforms!


Re: pointer escaping return scope bug?

2022-11-25 Thread Paul Backus via Digitalmars-d-learn

On Friday, 25 November 2022 at 14:07:28 UTC, ShadoLight wrote:
On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus 
wrote:
Since, in your example, `lf` has global lifetime, the compiler 
deduces that `lf.fp` also has global lifetime, and therefore 
there is nothing wrong with assigning it to `p`.


I follow your rationale, but for the life of me I cannot see 
how `lf` _"has global lifetime"_.


You're right, my terminology here is sloppy. I'm really talking 
about the memory pointed to by `lf`, not `lf` itself, so I should 
really say that `lf` *points to memory* with global lifetime (or 
perhaps "`*lf` has global lifetime").


Re: pointer escaping return scope bug?

2022-11-25 Thread ShadoLight via Digitalmars-d-learn

On Friday, 25 November 2022 at 14:07:28 UTC, ShadoLight wrote:

On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```

[snip]


I don't grok how `lf` can survive the local scope. Or am I 
missing something?


Perhaps because the local scope is not pushed as a separate 
(anonymous) function on the stack... if true then, yes, then `lf` 
will indeed have the same physical lifetime as main (and `p`)...?


On the other hand, if you add a destructor to `LockedFile`, it 
will be invoked at the end of the local scope, not the end of 
main.


I find it a bit confusing what the term "lifetime" should pertain 
to in the case of variables declared inside a local scope inside 
a function - destructor invocation or physical existence of the 
variable on the stack?


But this has no bearing on the heap allocation and the lifetime 
of `p` in the example.




Re: pointer escaping return scope bug?

2022-11-25 Thread ShadoLight via Digitalmars-d-learn

On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus wrote:
On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven 
wrote:

Hi,
The following seems like a bug to me (reduced code, FILE* 
changed to int*):

```d
@safe:

struct LockedFile
{
private int* fps;

auto fp() return scope => fps;
}

void main()
{
int* p;
{
auto lf = LockedFile(new int);
p = lf.fp;
}
assert(p != null); // address escaped
}
```
There's no error with -dip1000.
I'll file this unless I overlooked something.


I think this is intended behavior, because you *do* get an 
error if you replace `new int` with a pointer to a stack 
variable; e.g.,


int local;
auto lf = LockedFile();

The `return scope` qualifier on the method does *not* mean "the 
return value of this method is `scope`". It means "this method 
may return one of this object's pointers, but does not allow 
them to escape anywhere else." In other words, it lets the 
compiler determine that the return value of `lf.fp` has *the 
same* lifetime as `lf` itself.


Since, in your example, `lf` has global lifetime, the compiler 
deduces that `lf.fp` also has global lifetime, and therefore 
there is nothing wrong with assigning it to `p`.


I follow your rationale, but for the life of me I cannot see how 
`lf` _"has global lifetime"_.


Looks to me like `lf` is a value instance of the `LockedFile` 
struct (so on the stack) in a local scope inside main. I fully 
agree that the above code is not problematic, but isn't that 
because `p` is declared outside this local scope, and the 
allocation that happens inside the local scope (in the `lf` 
constructor) is on the heap, so the allocation (now assigned to 
`p`) survives the end of the local scope (and the end of the life 
of `lf`) since it is `p` that has global lifetime?


I don't grok how `lf` can survive the local scope. Or am I 
missing something?






Re: Assigning parameter on entry to a function and assigning back on exit

2022-11-25 Thread Ali Çehreli via Digitalmars-d-learn

On 11/25/22 05:06, Victor Porton wrote:

>> A function argument that is both input and output, may be passed to
>> the function either as reference or do two assignments: on entry of
>> the function it is assigned to the parameter, on exit it is assigned
>> back.

The way I understand it with C, C++, and D, if there were such an 
assignment back, that could only be performed by the caller. I don't 
think the ABIs of those languages support that behavior.


I think there is only pass by reference for out parameters.

Ali



Re: Assigning parameter on entry to a function and assigning back on exit

2022-11-25 Thread Victor Porton via Digitalmars-d-learn

On Friday, 25 November 2022 at 11:01:09 UTC, Victor Porton wrote:

Somewhere in my brain memory, it was written:

A function argument that is both input and output, may be 
passed to the function either as reference or do two 
assignments: on entry of the function it is assigned to the 
parameter, on exit it is assigned back. Whether it is a 
reference or two assignments depends on the reference semantics 
of the type.


Now I can't find this in the reference manual. Please help to 
refresh/correct my memory.


Probably, in my memory this was stored regarding Ada and 
misattributed to D, wasn't it?


Does D have or no this kind of feature?


Assigning parameter on entry to a function and assigning back on exit

2022-11-25 Thread Victor Porton via Digitalmars-d-learn

Somewhere in my brain memory, it was written:

A function argument that is both input and output, may be passed 
to the function either as reference or do two assignments: on 
entry of the function it is assigned to the parameter, on exit it 
is assigned back. Whether it is a reference or two assignments 
depends on the reference semantics of the type.


Now I can't find this in the reference manual. Please help to 
refresh/correct my memory.