Skip to content

Replace memset with constexpr fill_n in bigint::align and fix memset count to account for sizeof T #4471

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

Merged
merged 4 commits into from
Jun 23, 2025

Conversation

Tomek-Stolarczyk
Copy link
Contributor

Had an issue with a particularly pedantic compiler that flagged the use of memset (a non-constexpr labeled function) in the use of bigint::align when it's marked FMT_CONSTEXPR=constexpr.
Using the internal fill_n allows the function to stay constexpr and use memset when it isn't.

Also noticed that when memset is used in fill_n, it doesn't account for sizeof(T) so when using fill_n to clear a large buffer, memset will leave a portion of the buffer unmodified.

@vitaut
Copy link
Contributor

vitaut commented Jun 19, 2025

What compiler/version are you referring to and what is the full error?

Copy link
Contributor

@vitaut vitaut left a comment

Choose a reason for hiding this comment

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

Thanks for the PR but please provide more details per my earlier comment and address warnings reported in CI: https://github.com/fmtlib/fmt/actions/runs/15737439842/job/44421626034?pr=4471

@Tomek-Stolarczyk
Copy link
Contributor Author

What compiler/version are you referring to and what is the full error?

I couldn't reproduce this on public compilers but the error message recieved was
deps/fmt/11.2.0/include/fmt/format.h: In member function 'constexpr void fmt::v11::detail::bigint::align(const fmt::v11::detail::bigint&)': deps/fmt/11.2.0/include/fmt/format.h:2731:11: error: call to non-'constexpr' function 'void* memset(void*, int, size_t)' memset(bigits_.data(), 0, to_unsigned(exp_difference) * sizeof(bigit));

Thanks for the PR but please provide more details per my earlier comment and address warnings reported in CI:

Will work on getting the builds green, thanks

…c assert. Use a 0U to initialize bigits_.data()
@@ -2799,7 +2800,7 @@ class bigint {
bigits_.resize(to_unsigned(num_bigits + exp_difference));
for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
bigits_[j] = bigits_[i];
memset(bigits_.data(), 0, to_unsigned(exp_difference) * sizeof(bigit));
fill_n(bigits_.data(), to_unsigned(exp_difference), 0U);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why U?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

bigit is a uint32_t so bigits_.data() returns a uint32_t*. 0U is the unsigned literal for 0. I could use fill_n(bigits_.data(), to_unsigned(exp_difference), to_unsigned(0)); if that's better but thought using the literal U would convey the same meaning. LMK if you prefer I change it to something else. The 0 is by default signed so I got a signed/unsigned warning.

@vitaut vitaut merged commit 953cffa into fmtlib:master Jun 23, 2025
45 checks passed
@vitaut
Copy link
Contributor

vitaut commented Jun 23, 2025

Merged, thanks!

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