-
-
Notifications
You must be signed in to change notification settings - Fork 22k
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
Make freed object different than null in comparison operators (reverted) #73896
Make freed object different than null in comparison operators (reverted) #73896
Conversation
9b68ffd
to
f7d140b
Compare
I have a question:
|
It uses the ObjectID for comparison. Even if the address is the same, the ID should be different. |
I'm still not sure if a freed Object should be truthy, given the following: var a = Node.new()
a.free()
if a:
# Do something with a This would generate errors since if is_instance_valid(a):
# ... Which is not as intuitive and require extra bookkeeping. So maybe the best option is to make |
Would one reason for a freed object not being falsy that on release you don't want the VM to be checking validity all the time, and therefore users are expected to use Many other areas of Godot perform validity tests only on debug, to let the user warn something is not right, with the hope that they will fix it so release builds don't crash. |
That is more of an argument to having a freed object equivalent The main question is: do we want users to shoot themselves in their feet so they can learn proper memory handling or should we help them with an easier construct? IMO forcing the user to use |
With regards to #73896 (comment): I tend to agree with the sentiment that |
f7d140b
to
fe2e876
Compare
Updated the PR to consider a freed object to be falsy, so |
Yeah, this way you can also clearly distinguish between "this value was never set/was explicitly nulled" and "this value has been destroyed". I found this PR because I was considering an architecture for special abilities that might very well be interested in knowing whether a given object reference was ever assigned in the first place. |
This is so everything is consistent, as a freed object is not equivalent to `null` in general. The booleanization of a freed object still returns `false` to work as an easy check for validity of objects. Similarly, the negation of a freed object returns `true`. Also makes freed objects different from each other (if they are not the same reference).
fe2e876
to
150b50c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong personal opinion, but the approach is consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in support of this solution, and it helps in various contexts
Thanks! Reduz mentioned that this may make things slower now, but he didn't lean one way or another. So I'm fully trusting George and Pedro with this. |
If I may, I feel like deleted objects being not equal to null is, at the very least, a major breaking change. It also does not make sense to me to ever need to distinguish between a deleted object and null, since both mean that there is no more value there. Null means an absence of value, a deleted object is has become absent. If such distinction is really needed, I think it should be a separate function like is_object_deleted or something of that sort, instead of making it not equal to null which will probably subtly break a lot of people's projects in addition to being NOT how other engines do it (e.g. unity, where a deleted object is in fact equal to null). |
They do not though, null means it's explicitly empty, this is true in other languages as well, please see the linked issue for the reasoning for this change, it's been extensively discussed, and been in the works for a long time in which objections could have been raised 🙂 You will also see this is a return to the correct behaviour used in 3.x The previous behaviour was classed as a bug, and relying on it isn't safe and I'd not call that breaking compatibility, the behaviour was broken, the correct way to handle this before and after this change is to use The change was also highlighted in the dev release so anyone can see it and adjust accordingly if they depended on the incorrect behaviour, but as this is not something people should have depended on I don't think it's valid to call it a breakage |
After discussing with the GDScript and Core teams, we decided to revert this for now as there are still some aspects where we're not 100% sure what's the best behavior. We'll revisit this for a future release with more caution on how to avoid breaking user expectations and use cases, while fixing the inconsistency in the handling of freed objects. |
This is so everything is consistent, in particular with booleanization of objects.
Now freed objects are considered a truthy value to agree with the fact they are different than null.Edit: I reversed this so freed objects are considered a falsy value instead, since I believe this is more intuitive and useful.Also makes freed objects different from each other (if they are not the same reference).
Fix #59816