Skip to content

Conversation

@mikael-s-persson
Copy link
Contributor

Fixed undefined behavior with log10 cast of fractional doubles.
Detected by UBSan

What does this change do?

Fixed undefined behavior with log10 cast of fractional doubles. log10 for values less than 1 result in a negative result, static-casting to size_t is undefined.

Is it related to an exisiting bug report or feature request?

No. Example error:

external/tomlplusplus~/toml.hpp:16978:41: runtime error: -2.05916 is outside the range of representable values of type 'unsigned long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior external/tomlplusplus~/toml.hpp:16978:41

Pre-merge checklist

  • I've read CONTRIBUTING.md
  • I've rebased my changes against the current HEAD of origin/master (if necessary)
  • [n/a] I've added new test cases to verify my change
  • I've regenerated toml.hpp (how-to)
  • [n/a] I've updated any affected documentation
  • [n/a] I've rebuilt and run the tests with at least one of:
    • [n/a master is broken] Clang 8 or higher
    • [n/a master is broken] GCC 8 or higher
    • MSVC 19.20 (Visual Studio 2019) or higher
  • [n/a] I've added my name to the list of contributors in README.md

Copy link
Owner

@marzer marzer left a comment

Choose a reason for hiding this comment

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

Oooh, nice find, thanks! 🎉

@marzer marzer merged commit 708fff7 into marzer:master Jun 11, 2025
11 checks passed
@towerpark
Copy link

I got the following warning with the change from this PR in one of my development environments (Clang 10 & libstdc++ 8):

.../tomlplusplus/include/toml++/impl/toml_formatter.inl:94:41:
warning: using integer absolute value function 'abs' when argument is of floating
point type [-Wabsolute-value]
    return weight + static_cast<size_t>(abs(log10(val))) + 1u;
                                        ^
.../tomlplusplus/include/toml++/impl/toml_formatter.inl:94:41: note: use function
'std::abs' instead
    return weight + static_cast<size_t>(abs(log10(val))) + 1u;
                                        ^~~
                                        std::abs

However, my other environment with a newer toolchain (Clang 16 & libstdc++ 10) does not complain. I didn't dig in the environments to find out the root cause, but I think it's probably because the newer environment brings the C++ overloads into the global namespace by something like using std::abs;, whereas the older one doesn't do that, leaving abs() resolved to the C version (int abs(int) from stdlib.h) .

If older toolchains are not unsupported, it's better to prefix the abs() function with std::.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants