Re: MobI? Really?

2021-09-21 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 21 September 2021 at 16:14:52 UTC, Chris_D wrote:

Thanks for the replies.

jfondren: Sorry, but I am talking about documentation.  For me, 
online web pages don't qualify; they are in the cloud, unreal, 
with no substance.  Does anyone really read 300 pages online, 
in a web browser?  Of course not.


I do! As far as I know, that's how most D users read the D docs. 
The docs do ship with DMD, though. On Windows, there's an `html` 
folder in the installation tree. I don't know how they're 
installed on other platforms.


Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread eugene via Digitalmars-d-learn

On Tuesday, 21 September 2021 at 20:47:41 UTC, H. S. Teoh wrote:

Век живи - век учись. А дураком помрёшь.

:)

"Век живи  - век учись, всё равно дураком помрёшь."

is correct version. :)




Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread eugene via Digitalmars-d-learn

On Tuesday, 21 September 2021 at 20:47:41 UTC, H. S. Teoh wrote:
And since stopper isn't used anymore after declaration, an 
optimizing compiler is free to assume that it's not needed 
afterwards, so it's not obligated to keep the reference alive 
until the end of the function.


It was not obvious for me,
I thought lifetimes always
lasts until the end of a scope
(main in this case).



Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Sep 21, 2021 at 08:36:49PM +, eugene via Digitalmars-d-learn wrote:
> On Tuesday, 21 September 2021 at 20:17:15 UTC, eugene wrote:
> 
> > Now, change operation order in the main like this:
> 
> Actually, all proposed 'fixes'
> 
> - use stopper somehow in the end (writeln(stopper.sg0.number))
> - change operation order
> - etc
> 
> are strange. I mean it's strange (for me) that these
> fixes make garbage collector behave as needed.

It's not strange.  You're seeing these problems because you failed to
inform the GC about the dependency between Main and stopper. So it's
free to assume that these are two independent, unrelated objects, and
therefore it can collect either one as soon as there are no more
references to it.

And since stopper isn't used anymore after declaration, an optimizing
compiler is free to assume that it's not needed afterwards, so it's not
obligated to keep the reference alive until the end of the function.

Since in actually there *is* a dependency between these objects, the
most "correct" solution is to include a reference to stopper somewhere
in Main. Then the GC would be guaranteed never to collect stopper before
Main becomes unreferenced.


T

-- 
Век живи - век учись. А дураком помрёшь.


Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Sep 21, 2021 at 08:17:15PM +, eugene via Digitalmars-d-learn wrote:
[...]
> ```d
> void main(string[] args) {
> 
> auto Main = new Main();
> Main.run();
> 
> auto stopper = new Stopper();
> stopper.run();
> ```
[...]
> ```d
> void main(string[] args) {
> 
> auto Main = new Main();
> auto stopper = new Stopper();
> 
> Main.run();
> stopper.run();
> ```
[...]
> Everything is Ok now, stopper is not collected soon after start.
> So the question is how this innocent looking change can affect GC
> behavior so much?...

In the first example, the compiler sees that the lifetime of Main is
disjoint from the lifetime of stopper, so it's free to reuse the same
stack space (or register(s)) to store both variables. (This is a pretty
standard optimization FYI.) So the line `auto stopper = new Stopper();`
would overwrite the reference to Main, and the GC would see Main as an
unreferenced object and may collect it at any point after the line
`Main.run();`.

In the second case, since the lifetimes of Main and stopper overlap, the
compiler (probably) conservatively assumes that their lifetimes last
until the end of the function, and so reserves disjoint places for them
on the stack.  This does not mean you're 100% safe, however. A
sufficiently optimizing compiler may determine that since Main and
stopper are independent, it is free to reorder the code such that the
two lifetimes are independent, and therefore end up with the same
situation as the first example.

If Main really depends on the existence of stopper, I'd argue that it
really should store a reference to stopper somewhere, so that as long as
Main is not unreferenced the GC would not collect stopper.


T

-- 
What's an anagram of "BANACH-TARSKI"?  BANACH-TARSKI BANACH-TARSKI.


Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread eugene via Digitalmars-d-learn

On Tuesday, 21 September 2021 at 20:17:15 UTC, eugene wrote:


Now, change operation order in the main like this:


Actually, all proposed 'fixes'

- use stopper somehow in the end (writeln(stopper.sg0.number))
- change operation order
- etc

are strange. I mean it's strange (for me) that these
fixes make garbage collector behave as needed.




Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread jfondren via Digitalmars-d-learn

On Tuesday, 21 September 2021 at 20:17:15 UTC, eugene wrote:

Now, change operation order in the main like this:

```d
void main(string[] args) {

auto Main = new Main();
auto stopper = new Stopper();

Main.run();
stopper.run();
```

```
d-lang/edsm-in-d-simple-example-2 $ ./test | grep STOPPER
'STOPPER' registered 5 (esrc.Signal)
'STOPPER' registered 6 (esrc.Signal)
'STOPPER @ INIT' got 'M0' from 'SELF'
'STOPPER' enabled 5 (esrc.Signal)
'STOPPER' enabled 6 (esrc.Signal)
```

Everything is Ok now,


I don't think this is reliably OK. If you're not using Stopper 
later in the function, and if there are no other references to 
it, then the GC can collect it. It just has no obligation to 
collect it, so minor differences like this might prevent that 
from happening for particular compilers/options/versions.


C# and Go have 'keepalive' functions to avoid similar behavior, 
and Java's just as aggressive about potential collection. It's 
just something that mostly doesn't matter until it becomes an 
incredibly weird bug with code like yours.


Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Sep 21, 2021 at 07:42:48PM +, jfondren via Digitalmars-d-learn 
wrote:
> On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote:
> > I do not understand at all why GC considers those sg0 and sg1 as
> > unreferenced.
> > And why old gdc (without -Os) and old ldc do not.
> 
> Conclusion:
> 
> There's nothing special about sg0 and sg1, except that they're part of
> Stopper. The Stopper in main() is collected before the end of main()
> because it's not used later in the function and because there are
> apparently no other references to it that the GC can find (because the
> only reference is hidden inside the Linux epoll API).

Quick and dirty workaround: keep references to those objects in static
variables to prevent GC collection:

auto myFunc(...) {
static MyType* dontCollect = null;

MyType* obj = new MyObject(...);
dontCollect = obj;
scope(exit) dontCollect = null; // may collect after function 
exits

... // function body goes here
}


T

-- 
Verbing weirds language. -- Calvin (& Hobbes)


Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread eugene via Digitalmars-d-learn

On Tuesday, 21 September 2021 at 19:42:48 UTC, jfondren wrote:

On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote:
There's nothing special about sg0 and sg1, except that they're 
part of Stopper. The Stopper in main() is collected before the 
end of main() because it's not used later in the function


Okay, but how could you explain this then

```d
void main(string[] args) {

auto Main = new Main();
Main.run();

auto stopper = new Stopper();
stopper.run();
```

```
d-lang/edsm-in-d-simple-example-2 $ ./test | grep STOPPER
'STOPPER' registered 5 (esrc.Signal)
'STOPPER' registered 6 (esrc.Signal)
'STOPPER @ INIT' got 'M0' from 'SELF'
'STOPPER' enabled 5 (esrc.Signal)
'STOPPER' enabled 6 (esrc.Signal)
___!!!___edsm.StageMachine.~this(): STOPPER destroyed...
   !!! esrc.EventSource.~this() : esrc.Signal (owner STOPPER, fd 
= 5) this @ 0x7fc9ab1a9150
   !!! esrc.EventSource.~this() : esrc.Signal (owner STOPPER, fd 
= 6) this @ 0x7fc9ab1a9180

```

Now, change operation order in the main like this:

```d
void main(string[] args) {

auto Main = new Main();
auto stopper = new Stopper();

Main.run();
stopper.run();
```

```
d-lang/edsm-in-d-simple-example-2 $ ./test | grep STOPPER
'STOPPER' registered 5 (esrc.Signal)
'STOPPER' registered 6 (esrc.Signal)
'STOPPER @ INIT' got 'M0' from 'SELF'
'STOPPER' enabled 5 (esrc.Signal)
'STOPPER' enabled 6 (esrc.Signal)
```

Everything is Ok now, stopper is not collected soon after start.
So the question is how this innocent looking change
can affect GC behavior so much?...

Misaligned pointers are one way to hide objects from the GC but 
in this case they really weren't relevant.


For sure.




Re: Program crash: GC destroys an object unexpectedly

2021-09-21 Thread jfondren via Digitalmars-d-learn

On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote:
I do not understand at all why GC considers those sg0 and sg1 
as unreferenced.

And why old gdc (without -Os) and old ldc do not.


Conclusion:

There's nothing special about sg0 and sg1, except that they're 
part of Stopper. The Stopper in main() is collected before the 
end of main() because it's not used later in the function and 
because there are apparently no other references to it that the 
GC can find (because the only reference is hidden inside the 
Linux epoll API).


More discussion:

https://forum.dlang.org/thread/siajpj$3p2$1...@digitalmars.com
http://dpldocs.info/this-week-in-d/Blog.Posted_2021_09_20.html

Misaligned pointers are one way to hide objects from the GC but 
in this case they really weren't relevant. I just had a confused 
idea of the epoll API, because I'd only ever used it with a 
single static array that all epoll functions referenced, 
similarly to poll(). But actually epoll copies the event 
structures that you give it, and returns them on epoll_wait. 
That's wild.


Re: MobI? Really?

2021-09-21 Thread jfondren via Digitalmars-d-learn

On Tuesday, 21 September 2021 at 16:14:52 UTC, Chris_D wrote:
jfondren: Sorry, but I am talking about documentation.  For me, 
online web pages don't qualify; they are in the cloud, unreal, 
with no substance.  Does anyone really read 300 pages online, 
in a web browser?  Of course not.


You can download them to a local copy, and you can generate them 
locally. But usually I am not reading 300 pages but going to a 
specific part of the documentation to look a specific thing up, 
and there I'm usually online anyway.


As a thing to read from beginning to end rather than a spot 
reference I think the current spec would be very wanting for a 
few reasons, like internal hyperlinks and little of the 
justificatory text that 'annotated' specifications tend to have. 
For a recent example, in https://dlang.org/spec/garbage.html it 
just says "Do not misalign pointers if those pointers may point 
into the GC heap". Why not? If you can get away with it on a 
particular architecture, maybe it's fine? Actually, it's a big 
deal.


What I'd like is Perl's offline documentation. Just type 'perldoc 
perl' into a unix system and look at it. Or 'perldoc -f stat', 
'perldoc -q columns'.



Jordi Sayol: PDF!  ePub!  Now that's what I call documentation!

But that's on SourceForge.  My first port of call to learn 
about D was, and is, dlang.org, where the *only* links to the 
"D Programming Language Specification" in any downloadable 
format are for the Mobi.


  Chris


I haven't had consistent results with requesting updates to the 
online docs, but you could try just adding a link to this page. 
There are other offsite links and they occasionally need tending 
to, as well.


A more immediate place to make a change is 
https://wiki.dlang.org/The_D_Programming_Language , where it'd be 
very easily to slide a few extra links onto the 'D Language 
Specification' link at the top right.


The wiki isn't only accessible through Community/Wiki; several of 
the Resources links on dlang.org also point to it.


Re: MobI? Really?

2021-09-21 Thread Chris_D via Digitalmars-d-learn

Thanks for the replies.

jfondren: Sorry, but I am talking about documentation.  For me, 
online web pages don't qualify; they are in the cloud, unreal, 
with no substance.  Does anyone really read 300 pages online, in 
a web browser?  Of course not.


Jordi Sayol: PDF!  ePub!  Now that's what I call documentation!

But that's on SourceForge.  My first port of call to learn about 
D was, and is, dlang.org, where the *only* links to the "D 
Programming Language Specification" in any downloadable format 
are for the Mobi.


  Chris



Re: Why dtor are not executed when removing a struct from associative arrays?

2021-09-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/21/21 2:06 AM, Tejas wrote:

On Monday, 20 September 2021 at 18:13:53 UTC, Steven Schveighoffer wrote:

On 9/20/21 10:22 AM, Tejas wrote:
In case you still want to delete stuff deterministically despite what 
Steve said, I suggest you make your `struct` a reference and use 
`core.memory.__delete`(not recommended to use this carelessly, btw)


Do not call `__delete` here, use `destroy`. `__delete` will attempt to 
deallocate the block, which likely will fail since the key comes 
before the value, and GC.free on an interior pointer (I think) fails.


But if it succeeded, it would not be good. This leaves a dangling 
pointer inside the AA. Rehashing the AA likely would result in a 
memory corruption.


If you use destroy, the destructor will be called by the GC as well, 
but a struct should properly handle destroying the .init value.




It doesn't succeed when object is stack allocated, otherwise it works; 
that's why I suggested changing `S` to `S*`.


Oh! I missed that subtle change. I thought you were deleting a pointer 
to S that lives in a `S[int]`.


I still recommend against this because you can easily get a dangling 
pointer that way. Aside from that, if you are careful enough not to 
store a retrieved S* from the aa, you could do that. It will incur one 
extra allocation per element, which is not ideal.


Using destroy should be the most effective and safest mechanism.

-Steve


better c fibers

2021-09-21 Thread Abby via Digitalmars-d-learn

Hi there,
I'm new in dlang I specially like betterC. I was hoping that d 
fibers would be implemented in without using classes, but there 
are not. Is there another way how to use async/await in dlang 
better c?


Thank you for your help
Abby