Skip to content

Document casting INF/NAN to int is undefined behavior - #121812

Open
Arecher wants to merge 5 commits into
godotengine:masterfrom
Arecher:Document-casting-INF/NAN-to-int-is-undefined-behavior
Open

Document casting INF/NAN to int is undefined behavior#121812
Arecher wants to merge 5 commits into
godotengine:masterfrom
Arecher:Document-casting-INF/NAN-to-int-is-undefined-behavior

Conversation

@Arecher

@Arecher Arecher commented Jul 27, 2026

Copy link
Copy Markdown
  • Extended warning to document int(INF) and int(NAN) return -9223372036854775808 on most platforms

What problem(s) does this PR solve?

Additional information

While I consider this a bug, it has been present since at least Godot 3.x, so it is better documented until fixed.

- Extended warning to document `int(INF)` and `int(NAN)` return `-9223372036854775808` on most platforms
@Arecher
Arecher requested review from a team as code owners July 27, 2026 03:09
Comment thread modules/gdscript/doc_classes/@GDScript.xml Outdated
Arecher added 2 commits July 27, 2026 07:38
They're meant to be code snippets rather than references to the documentation.
Comment thread modules/gdscript/doc_classes/@GDScript.xml Outdated

@AThousandShips AThousandShips left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@bruvzg

bruvzg commented Jul 28, 2026

Copy link
Copy Markdown
Member

I do think removing the explicit value means the documentation won't be surfaced when users google for the keywords INF and -9223372036854775808/ negative value, which (going by the half-dozen bug reports) is how this issue is mostly referenced to. But I understand the reason for removing it.

Documentation can include keywords="" field, which is used for search but not displayed in UI.

diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index a84c59b4ee..6f78d07d9a 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -285,11 +285,11 @@
                <constant name="TAU" value="6.28318530717959">
                        The circle constant, the circumference of the unit circle in radians. This is equivalent to [code]PI * 2[/code], or 360 degrees in rotations.
                </constant>
-               <constant name="INF" value="inf">
+               <constant name="INF" value="inf" keywords="-9223372036854775808,9223372036854775808,-9223372036854775807,9223372036854775807">
                        Positive floating-point infinity. This is the result of floating-point division when the divisor is [code]0.0[/code]. For negative infinity, use [code]-INF[/code]. Dividing by [code]-0.0[/code] will result in negative infinity if the numerator is positive, so dividing by [code]0.0[/code] is not the same as dividing by [code]-0.0[/code] (despite [code]0.0 == -0.0[/code] returning [code]true[/code]).
                        [b]Warning:[/b] Numeric infinity is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer number by [code]0[/code] will not result in [constant INF] and will result in a run-time error instead.
                </constant>
-               <constant name="NAN" value="nan">
+               <constant name="NAN" value="nan" keywords="-9223372036854775808,9223372036854775808,-9223372036854775807,9223372036854775807">
                        "Not a Number", an invalid floating-point value. It is returned by some invalid operations, such as dividing floating-point [code]0.0[/code] by [code]0.0[/code].
                        [constant NAN] has special properties, including that [code]!=[/code] always returns [code]true[/code], while other comparison operators always return [code]false[/code]. This is true even when comparing with itself ([code]NAN == NAN[/code] returns [code]false[/code] and [code]NAN != NAN[/code] returns [code]true[/code]). Due to this, you must use [method @GlobalScope.is_nan] to check whether a number is equal to [constant NAN].
                        [b]Warning:[/b] "Not a Number" is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer [code]0[/code] by [code]0[/code] will not result in [constant NAN] and will result in a run-time error instead.
Screenshot 2026-07-28 at 14 30 35

@Arecher

Arecher commented Jul 28, 2026

Copy link
Copy Markdown
Author

Interesting! That would be an improvement for being able to surface the documentation for sure.

I could add that if desired, although I do not understand the impact of changing:

--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml

@bruvzg

bruvzg commented Jul 28, 2026

Copy link
Copy Markdown
Member

I could add that if desired, although I do not understand the impact of changing

This is just a part of diff file format, ignore it if you adding it manually.

@Arecher

Arecher commented Jul 28, 2026

Copy link
Copy Markdown
Author

Is there a way to add an invisible note to the keywords, so if this bug gets fixed in the future, it is clear why these seemingly random int values are in the documentation?

@AThousandShips

Copy link
Copy Markdown
Member

There's no bug here, this is undefined behavior in the C++ language, conversions from floating point values to integers are defined as "If the truncated value cannot fit into the destination type, the behavior is undefined (even when the destination type is unsigned, modulo arithmetic does not apply).", so we'd have to do some arbitrary decision as to what to make it become in those cases

@Arecher

Arecher commented Jul 28, 2026

Copy link
Copy Markdown
Author

Right, from an implementation standpoint I agree there is no bug, but from a user perspective int(INF) returning -9223372036854775808* is clearly perceived as a bug due to how unexpected and counterintuitive it is. In issues where this got discussed, there seems to be relative consensus that it should be changed, just not how it should be changed (disabled completely, always return 0, return lowest/highest int, etc).

@AThousandShips

Copy link
Copy Markdown
Member

I disagree that casting INF to an int should have any reasonable result, any result at all would be wrong I'd say, INF is not the same as "the maximum value" so returning INT64_MAX would be incorrect

But something to discuss on the issue thread

@Repiteo

Repiteo commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Regardless of what casting ±INF to int should do, any change to that logic would be compatibility-breaking and is out of the scope of this PR. For the time being, documenting the existing behavior is sufficient

@Repiteo

Repiteo commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Could you squash your commits? See our pull request guidelines for more information

@Repiteo Repiteo modified the milestones: 4.x, 4.8 Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants