-
-
Notifications
You must be signed in to change notification settings - Fork 21k
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
Should bitfields types be unsigned integers instead of signed integers? #88962
Comments
It has come up before, see e.g. #61757 , #88424 (comment) . |
Thanks for those! So I guess the next discussion to be had is if we should extend that enforcement of unsigned integers to the class db level for bitflags: godot/core/object/class_db.cpp Line 949 in 81f3d43
What impact that may have on sdks like Steam? Will it be compatible still and / or is there an expected reason it is negative on Windows? |
To bring this to a discussion about concrete actionables -- we currently have this in the GDExtension C header: typedef int64_t GDExtensionInt;
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant)(
GDExtensionClassLibraryPtr p_library,
GDExtensionConstStringNamePtr p_class_name,
GDExtensionConstStringNamePtr p_enum_name,
GDExtensionConstStringNamePtr p_constant_name,
GDExtensionInt p_constant_value,
GDExtensionBool p_is_bitfield
); The signed I see two options: 1. Add a new C function with the correct type// only for bitfields, not enums
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassBitfieldConstant)(
GDExtensionClassLibraryPtr p_library,
GDExtensionConstStringNamePtr p_class_name,
GDExtensionConstStringNamePtr p_enum_name,
GDExtensionConstStringNamePtr p_constant_name,
uint64_t p_constant_value, // now unsigned
// no p_is_bitfield value
); We can either keep the old 2. Keep signature, improve docsIf you think moving away from the existing signature is too much of a change, we could go for this approach. Clearly specify that |
Do you have any idea the extent of the impact a change like this could have, @Bromeon? At least at my day job, we typically err on the side of a combination of both of these, starting with (2) and at some point introducing the new API in conjunction with the deprecation of the old toward the EoL of the current major just before moving to the next major when there is a large impact. |
The existing API would keep working; GDExtension generally provides backwards compatibility down to Godot 4.1. So no one would be forced to update. Migration would likely be quite straightforward, too: since the underlying value is only a bit pattern and has no numeric meaning, one can simply use |
I'm in favor the new C function. I've seen a few libraries that use -1 as shorthand for "all flags on." It's very convenient, but you can run into trouble when casting from a smaller unsigned integer to a larger signed one because -1 is a different set of bits depending on your integer size. Enums that have bitfields (e.g., Steamworks API) are extra fun because the default type for enums can depend on the compiler (see #61757). Unsigned bitfields prevent this. For the new API, I have a few questions:
|
Very good question. I originally intended to use the existing Maybe this is something to accept, I'm not sure if promoting bitfields to their own independent "domain" would be desired, and it would also be problematic for backwards compatibility. Or the existing method only returns constants registered the old way, and bitfields (with Or it's creating too much complexity 🤔 my intention was mostly to make clear to GDExtension developers that bitfields are really just bits, and the signedness is irrelevant (thus unsigned, because more common). I'm not sure if we should rework the whole way how constants are handled internally in Godot.
One problem I see is that the most common Godot language, GDScript, does not support unsigned integers. So if you registered 0xFFFFFFFF as unsigned, it would have a different value in GDScript. Godot itself doesn't differentiate between signed and unsigned constants, so this information would be lost. At that point, it's probably better to stick to the supported While you could abuse the bitfield registration to pass in |
Discussed at the GDExtension, and we decided to:
|
Tested versions
Pop OS 22.04: Godot Engine v4.3.dev.mono.custom_build.bbb3531fa
Windows 10: Godot Engine v4.3.dev.mono.custom_build.bbb3531fa
System information
Pop OS 22.04, Windows 10
Issue description
We found that Windows was actually treating 0xffffffff bitflags as a signed integer with a value of -1 when compared to Linux where it was treated as unsigned and assigned a value of 4294967295.
This resulted in Gdext panicing when generating Godot bindings as seen in this PR for the fix over here: godot-rust/gdext#627
Godot currently uses signed integers when binding all of its constants including bitflags:
godot/core/object/class_db.cpp
Line 949 in 81f3d43
So we are seeking further information and discussion around the data type that Godot should enforce for bitflags. Should it stay with the currently signed value? Are there instances where negative values make sense for bitflags? Is there a reason Steam's sdk evaluates to this negative value on Windows and is this expected behavior? If Godot changed to unsigned, would it still be compatible with Steam?
I don't expect all of these questions to necessarily be answered by the Godot team, but I wanted to get the discussion started while we also change the datatype on the gdext side to match Godot's datatype.
Here are the current issues / prs for reference:
godotsteam: GodotSteam/GodotSteam#424
gdext: godot-rust/gdext#627
Steps to reproduce
Build godotsteam from here: https://github.com/CoaguCo-Industries/GodotSteam/tree/godot4.
Evaluate the bitflags as describe here: GodotSteam/GodotSteam#424
See that the constant on Linux is 4294967295
And the constant on Windows is -1
Minimal reproduction project (MRP)
https://github.com/CoaguCo-Industries/GodotSteam/tree/godot4
The text was updated successfully, but these errors were encountered: