Immediate-Mode-UI / Immediate-Mode-UI/Nuklear

Unsafe floating-point comparisons with '==' or '!='

Open
#793 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
11.4k
Forks
686
Avg merge
4d 1h
Merged PRs (30d)
3

Description

Comparison results of floating-point values with the `==` or `!=` operators depend on compiler optimizations, architecture and precision and there are corner cases like NaN, infinity or `-0.0`.

Tag 4.12.5 produces the following warnings in GCC and CLang using `-Wfloat-equal`:

```
../../nuklear.h:6546:10: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:6546:22: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:7297:11: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:7904:39: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:7939:16: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9340:34: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9340:49: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9363:34: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9363:49: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9387:22: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9387:37: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9411:19: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9411:31: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9433:31: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9433:43: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9609:18: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9609:31: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9709:18: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9709:31: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9736:18: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:9736:31: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:10245:21: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:10396:21: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:10486:21: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:10593:16: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:10642:11: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:13667:21: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:13667:47: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:14594:18: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:14759:11: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:14773:11: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:14775:16: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:14821:18: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:15070:20: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:15250:21: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:15449:16: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:15450:16: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:15451:19: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16141:10: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16193:17: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16193:33: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16311:14: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16348:35: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16355:22: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16377:66: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16417:32: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16421:31: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:16422:34: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:20383:50: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:20383:83: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:20383:123: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:21708:28: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:22084:16: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
../../nuklear.h:28043:32: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
```

Example warning sites:
```
../../nuklear.h: In function 'nk_atan2':
../../nuklear.h:6546:10: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
6546 | if(y == 0.0 && x == 0.0) return 0.0f;
```

```
../../nuklear.h: In function 'nk_panel_end':
../../nuklear.h:20383:50: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
20383 | int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta.y != 0;
```

Could it be that hard to reproduce anomalies of sliders, scroll bars may have to do something with these comparisons?

Contributor guide

Open the contributing guide

Research direction

Start in nuklear.h at the warning sites listed in the issue, especially nk_atan2 and nk_panel_end. Reproduce the GCC or Clang -Wfloat-equal warnings and inspect whether the floating-point comparisons correspond to slider or scrollbar anomalies. Done should establish whether these comparisons cause the reported behavior and identify the affected sites.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.