December 19, 2014
On 12/12/14 10:50 AM, Steven Schveighoffer wrote:
> On 12/12/14 7:52 AM, Ruslan Mullakhmetov wrote:

>> btw, i used suggested trackallocs.d and GC defenetely receives NO_SCAN
>>
>> before tag: 1 len: 2 ptr: 103A78058 root: 103A77000:8192 attr: APPENDABLE
>> gc_qalloc(41, NO_SCAN APPENDABLE ) cc: 29106 asz: 10152603, ti: null
>> ret: BlkInfo_(104423800, 64, 10)
>> after tag: 1 len: 3 ptr: 104423810 root: 104423800:64 attr: NO_SCAN
>> APPENDABLE
>
> This is good information, thanks. I will get back to you with a druntime
> branch to try. Can I email you at this address? If not, email me at the
> address from my post to let me know your contact, no reason to work
> through building issues on the public forum :)

For those who were interested, we were not able to solve this problem, and unfortunately Ruslan's company cannot keep trying to debug, they have moved on to another language :(

If anyone else has this kind of issue (array appending causing flags to change), please let me know, I would like to make sure this gets solved.

I am creating 2 fixes, one to fix the issue with the offset (in progress) and after that I will attempt to ensure any changes to a block's flags stick when the array is appended (I found at least one place in Phobos where this can cause a bug, but it's not affecting his code).

Ruslan, you may want to try the second fix when it has been added just to see if it helps.

The two bug reports are:

https://issues.dlang.org/show_bug.cgi?id=13854
https://issues.dlang.org/show_bug.cgi?id=13878

-Steve
March 25, 2015
On 12/09/2014 08:53 AM, Steven Schveighoffer wrote:

> On 12/9/14 11:17 AM, ketmar via Digitalmars-d-learn wrote:

>> that file can be already finalized. please remember that `~this()` is
>> more a finalizer than destructor, and it's called on *dead* object.

Agreed: D has a terminology issue here, what we call a "class destructor" is a "class finalizer". I have added D to the Wikipedia article:

  http://en.wikipedia.org/wiki/Finalizer

Now I want to improve some of my chapters.

>> here this means that any other object in your object (including
>> structs) can be already finalized at the time GC decides to call your
>> finalizer.

Although I know the fact above, I think ketmar makes a distinction (that is new to me) that a finalizer is a function that does not reference class members but a destructor does (or safely can).

> File is specially designed (although it's not perfect) to be able to
> close in the GC. Its ref-counted payload is placed on the C heap to
> allow access during finalization.
>
> That being said, you actually don't need to write the above in the class
> finalizer, _file's destructor will automatically be called.
>
>> just avoid "destructors" unless you *really* need that. in your case
>> simply let GC finalize your File, don't try to help GC. this is not C++
>> (or any other language without GC) and "destructors" aren't destructing
>> anything at all. "destructors" must clean up the things that GC cannot
>> (malloc()'ed memory, for example), and nothing else.
>>
>
> Good advice ;)
>
> I would say other than library writers, nobody should ever write a class
> dtor.
>
> -Steve

Can somebody elaborate on that guideline please. Given a case where runtime polymorphism is needed, so that we have to use classes, does the guideline simply mean that "arrange for manual cleanup" or is there more in that guideline? I am confused about the "library writers" part. :)

Thank you,
Ali

March 26, 2015
On 3/25/15 9:51 AM, Ali Çehreli wrote:
> On 12/09/2014 08:53 AM, Steven Schveighoffer wrote:
>
>  > On 12/9/14 11:17 AM, ketmar via Digitalmars-d-learn wrote:
>
>  >> that file can be already finalized. please remember that `~this()` is
>  >> more a finalizer than destructor, and it's called on *dead* object.
>
> Agreed: D has a terminology issue here, what we call a "class
> destructor" is a "class finalizer". I have added D to the Wikipedia
> article:
>
>    http://en.wikipedia.org/wiki/Finalizer
>
> Now I want to improve some of my chapters.
>
>  >> here this means that any other object in your object (including
>  >> structs) can be already finalized at the time GC decides to call your
>  >> finalizer.
>
> Although I know the fact above, I think ketmar makes a distinction (that
> is new to me) that a finalizer is a function that does not reference
> class members but a destructor does (or safely can).

Think of it this way -- a D destructor can access data from it's own object. This means it CAN access its own members that are structs or value types. It should NOT access referenced data, unless that data is allocated outside the GC.

In Tango, there was a finalizer and a destructor. The finalizer was called from the GC. The destructor was called when using the 'delete' operator explicitly (and I think it also called the finalizer afterward). Having this informational structure helps to know where to put what cleanup code. I would love it if druntime added this feature, or something similar.

>
>  > File is specially designed (although it's not perfect) to be able to
>  > close in the GC. Its ref-counted payload is placed on the C heap to
>  > allow access during finalization.
>  >
>  > That being said, you actually don't need to write the above in the class
>  > finalizer, _file's destructor will automatically be called.
>  >
>  >> just avoid "destructors" unless you *really* need that. in your case
>  >> simply let GC finalize your File, don't try to help GC. this is not C++
>  >> (or any other language without GC) and "destructors" aren't destructing
>  >> anything at all. "destructors" must clean up the things that GC cannot
>  >> (malloc()'ed memory, for example), and nothing else.
>  >>
>  >
>  > Good advice ;)
>  >
>  > I would say other than library writers, nobody should ever write a class
>  > dtor.
>  >
>  > -Steve
>
> Can somebody elaborate on that guideline please. Given a case where
> runtime polymorphism is needed, so that we have to use classes, does the
> guideline simply mean that "arrange for manual cleanup" or is there more
> in that guideline? I am confused about the "library writers" part. :)

Destructors should only be used to clean non-GC resources (and in terms of completeness, you should implement such a destructor). It is important to remember that the GC may NEVER get around to calling your destructor. This means you cannot depend on it releasing non-GC resources in a timely manner.

A good example is a file descriptor. If you have an object that contains a file descriptor you SHOULD have a destructor which closes the file descriptor if not already closed. However, you should NOT technically rely on it being called in a timely manner. For cases where you can do it synchronously, use a specific method to close the file descriptor.

There is a school of thought that says it is an error to rely on the GC to destroy the FD, so why even have the destructor. But I see no reason to leak the FD out of spite.

This is why I say it should be only library writers -- they are the ones creating wrapper objects and using low level operations.

Of course, this isn't a hard and fast rule.

-Steve
1 2 3 4
Next ›   Last »