digitalmars.D - Documentation of object.destroy
- Johan Engelen (32/32) Jan 02 2018 Hi all,
- Temtaime (2/35) Jan 02 2018 Why not zerofy the object ?
- Johan Engelen (3/4) Jan 02 2018 Please keep the discussion on the topic of documentation, thanks.
- Temtaime (4/10) Jan 02 2018 Documentation does not correspond with the actual behavior, so
- 12345swordy (3/6) Jan 02 2018 Destroy calls the finalized function. (Which last time I check
- Mike Franklin (7/14) Jan 02 2018 I think you meant "This function *is* used..."
- Petar Kirov [ZombineDev] (2/8) Jan 02 2018 +1
- Steven Schveighoffer (18/28) Jan 02 2018 It does something different depending on the type:
- jmh530 (4/10) Jan 02 2018 What's the monitor do? I see that in the ABI documentation, but
- Steven Schveighoffer (5/18) Jan 02 2018 The monitor is used to lock any object for synchronization.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/7) Jan 02 2018 A monitor queues/schedules processes that are calling methods of
- Johan Engelen (6/9) Jan 02 2018 I first wrote an extra one for just structs, but then decided to
- Johan Engelen (16/34) Jan 02 2018 Much obliged to anyone doing the effort of fixing and improving
Hi all, Link: https://dlang.org/library/object/destroy.html The documentation says "Destroys the given object and puts it in an invalid state. " However, this is not (strictly) true. What destroy() does is overwrite the object with T.init (or zeros), and we should explicitly mention that. Also, the documentation states "that it [the object destroyed] no longer references any other objects.", which is wrong as this code shows: ``` __gshared int global; struct S { int* pint = &global; } void main() { S s; int i; s.pint = &i; assert(s.pint != &global); destroy(s); assert(s.pint != &global); // fails } ``` https://run.dlang.io/is/SFbxNm How about: "Destroys the given object `obj` and puts `obj` in its `T.init` state. This function used to destroy an object such that any cleanup by the destructor or finalizer is done, and such that `obj` no longer references any other objects (unless `T.init` references other objects). This function does not initiate a GC cycle nor free any GC memory." regards, Johan
Jan 02 2018
On Tuesday, 2 January 2018 at 13:58:49 UTC, Johan Engelen wrote:Hi all, Link: https://dlang.org/library/object/destroy.html The documentation says "Destroys the given object and puts it in an invalid state. " However, this is not (strictly) true. What destroy() does is overwrite the object with T.init (or zeros), and we should explicitly mention that. Also, the documentation states "that it [the object destroyed] no longer references any other objects.", which is wrong as this code shows: ``` __gshared int global; struct S { int* pint = &global; } void main() { S s; int i; s.pint = &i; assert(s.pint != &global); destroy(s); assert(s.pint != &global); // fails } ``` https://run.dlang.io/is/SFbxNm How about: "Destroys the given object `obj` and puts `obj` in its `T.init` state. This function used to destroy an object such that any cleanup by the destructor or finalizer is done, and such that `obj` no longer references any other objects (unless `T.init` references other objects). This function does not initiate a GC cycle nor free any GC memory." regards, JohanWhy not zerofy the object ?
Jan 02 2018
On Tuesday, 2 January 2018 at 14:22:06 UTC, Temtaime wrote:Why not zerofy the object ?Please keep the discussion on the topic of documentation, thanks. -Johan
Jan 02 2018
On Tuesday, 2 January 2018 at 14:39:52 UTC, Johan Engelen wrote:On Tuesday, 2 January 2018 at 14:22:06 UTC, Temtaime wrote:Documentation does not correspond with the actual behavior, so fill a PR and that's all. Then why even this topic is created ?Why not zerofy the object ?Please keep the discussion on the topic of documentation, thanks. -Johan
Jan 02 2018
On Tuesday, 2 January 2018 at 13:58:49 UTC, Johan Engelen wrote:Hi all, Link: https://dlang.org/library/object/destroy.html [...]Destroy calls the finalized function. (Which last time I check it's still a c function)
Jan 02 2018
On Tuesday, 2 January 2018 at 13:58:49 UTC, Johan Engelen wrote:How about: "Destroys the given object `obj` and puts `obj` in its `T.init` state. This function used to destroy an object such that any cleanup by the destructor or finalizer is done, and such that `obj` no longer references any other objects (unless `T.init` references other objects). This function does not initiate a GC cycle nor free any GC memory."I think you meant "This function *is* used..." I suggest the following: Calls `obj`'s destructor and sets `obj` to its default initial state, `T.init`. This function does not initiate a GC cycle nor does it free any GC memory. Mike
Jan 02 2018
On Tuesday, 2 January 2018 at 15:13:46 UTC, Mike Franklin wrote:[..] I suggest the following: Calls `obj`'s destructor and sets `obj` to its default initial state, `T.init`. This function does not initiate a GC cycle nor does it free any GC memory. Mike+1
Jan 02 2018
On 1/2/18 8:58 AM, Johan Engelen wrote:Hi all, Link: https://dlang.org/library/object/destroy.html The documentation says "Destroys the given object and puts it in an invalid state. " However, this is not (strictly) true. What destroy() does is overwrite the object with T.init (or zeros), and we should explicitly mention that. Also, the documentation states "that it [the object destroyed] no longer references any other objects.", which is wrong as this code shows:It does something different depending on the type: Objects: calls rt_finalize on the object, which calls the dtor, deletes the monitor, rewrites the init value to the object, and THEN zeroes the vtable ptr. This last step makes it inoperable for anyone still holding a pointer to the object. This is why I think the docs are written the way they are. Interfaces: If this is a D object, casts to Object and calls destroy on it. Structs: calls the dtor (if it exists), destroys recursively all the data members of the struct, and then initializes the data to it's init state. Everything else: overwrites with the init data. More explicitly, destroying a pointer simply sets it to null, and does not destroy what it points at. I would actually recommend ddocing each of the overloads of destroy individually instead of lumping them together, identifying what happens with each one. -Steve
Jan 02 2018
On Tuesday, 2 January 2018 at 17:16:54 UTC, Steven Schveighoffer wrote:It does something different depending on the type: Objects: calls rt_finalize on the object, which calls the dtor, deletes the monitor, rewrites the init value to the object, and THEN zeroes the vtable ptr. This last step makes it inoperable for anyone still holding a pointer to the object. This is why I think the docs are written the way they are.What's the monitor do? I see that in the ABI documentation, but it doesn't really explain it...
Jan 02 2018
On 1/2/18 3:07 PM, jmh530 wrote:On Tuesday, 2 January 2018 at 17:16:54 UTC, Steven Schveighoffer wrote:The monitor is used to lock any object for synchronization. It's allocated on demand. https://dlang.org/spec/class.html#synchronized-classes -SteveIt does something different depending on the type: Objects: calls rt_finalize on the object, which calls the dtor, deletes the monitor, rewrites the init value to the object, and THEN zeroes the vtable ptr. This last step makes it inoperable for anyone still holding a pointer to the object. This is why I think the docs are written the way they are.What's the monitor do? I see that in the ABI documentation, but it doesn't really explain it...
Jan 02 2018
On Tuesday, 2 January 2018 at 20:07:11 UTC, jmh530 wrote:What's the monitor do? I see that in the ABI documentation, but it doesn't really explain it...A monitor queues/schedules processes that are calling methods of an object so that only one process is executing methods on a single object at any given point in time. https://en.wikipedia.org/wiki/Monitor_(synchronization)
Jan 02 2018
On Tuesday, 2 January 2018 at 17:16:54 UTC, Steven Schveighoffer wrote:I would actually recommend ddocing each of the overloads of destroy individually instead of lumping them together, identifying what happens with each one.I first wrote an extra one for just structs, but then decided to keep it all combined for all, to try and make things easier to remember. But maybe the differences are too large indeed. -Johan
Jan 02 2018
On Tuesday, 2 January 2018 at 17:16:54 UTC, Steven Schveighoffer wrote:On 1/2/18 8:58 AM, Johan Engelen wrote:Much obliged to anyone doing the effort of fixing and improving the doc. I think Steven made a nice start. I added some comments below.Hi all, Link: https://dlang.org/library/object/destroy.htmlIt does something different depending on the type: Objects: calls rt_finalize on the object, which calls the dtor, deletes the monitor, rewrites the init value to the object, and THEN zeroes the vtable ptr. This last step makes it inoperable for anyone still holding a pointer to the object. This is why I think the docs are written the way they are.rt_finalize is an implementation detail and shouldn't be in the docs here. Important to mention the re-init _and_ the obj still being in invalid state (vtable is implementation detail and may be left out).Interfaces: If this is a D object, casts to Object and calls destroy on it. Structs: calls the dtor (if it exists), destroys recursively all the data members of the struct, and then initializes the data to it's init state. Everything else: overwrites with the init data. More explicitly, destroying a pointer simply sets it to null, and does not destroy what it points at.I find "does not destroy what it points at" important to mention. (perhaps even with an explicit "you have to dereference the pointer to destroy what it points at"). Thanks, Cheers, Johan
Jan 02 2018