-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convention to separate releasing resources and invalidating memory #6299
Comments
For the name what about |
|
That's normal, and OK. This is a perfectly valid, well defined program: var x: i32 = 1234;
x = undefined;
x = undefined; Note that setting something to
HashMap is a good example - it has
I think that code is actually worse, because it's likely that deinitialization is cheaper clearing and maintaining data integrity. The original code is better: ask both to be deinitialized, then set self to undefined.
I suggest
This looks like it might be useful as a separate proposal |
To me it makes more sense for init to return a non-const instance and do the invalidation in deinit. Since the instance is closing the file at deinit, it's not logically const anyway. It shouldn't be used after deinit (because the file is closed) so invalidating makes sense. |
I don't think this proposal has anything actionable. There is always the need for There could also be a useful convention for I don't think |
When defining a struct that contains fields pointing to other structures/resources, the developer has to decide whether they want to include "memory invalidation" (setting memory to
undefined
) inside theirdeinit
function. For example:It seems like a reasonable choice to invalidate the memory of the struct to help catch bugs elsewhere in the code that could mistakenly try to use the structure after calling
deinit
. However, there are cases where the caller may not want to invalidate the memory or may not want to right away.In the example above, imagine that both
Foo
andBar
also made the decision to invalidate their memory inside theirdeinit
functions. This would mean that the memory for fieldsa
andb
will both be "invalidated" twice.Some data structures within the standard library solve this problem by providing an additional function alongside
deinit
that releases resources without invalidation. For example,HashMap
contains adeallocate
function which only releases its resources. Then itsdeinit
function just callsdeallocate
then invalidates its memory. This pattern allows the caller to release resources and choose when/where to invalidate the memory if at all.There are other structures within the standard library that could benefit from this pattern (i.e.
ArrayList
and friends). However, having a standardized method name to release without invalidation seems beneficial to the users that want to invoke the same semantics through the standard library. For this I propose a standardized name for a member function that releases resources without invalidation. Maybe something likedeinitNoInvalidate
? Having a longer name is a flag to the user that it's up to them to perform invalidation, and that it's the same asdeinit
except without the invalidation step.Given a solution like this, we can properly implement our original struct like this:
Now our struct only invalidates memory once, and other users who use our struct as a field will be able to do the same.
Another example of excluding memory invalidation inside
deinit
is when an application wants to create a const instance of a struct. For example, say you create a file handle wrapper type. Assuming the handle is the only data inside the struct, it's reasonable for an application to create a const version of it since the handle should never change. However, forcing memory invalidation just after releasing the handle would prevent an application from using that function.Variation: don't invalidate in deinit
Another solution is to just say that
deinit
should NEVER invalidate its own memory. Consequently this could be enforced by requiring thatdeinit
always takeself
as a value rather than a pointer. Then the decision to invalidate is left to the caller. With this variation the standard lib could define a function that always does both:One benefit of this variation is types don't have to include boilerplate to define their own function that both releases and invalidates.
The text was updated successfully, but these errors were encountered: