Re: pointer escaping return scope bug?
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?)
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?)
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?
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?
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?
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
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
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
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.