fmt icon indicating copy to clipboard operation
fmt copied to clipboard

Constexpr formatted_size

Open marksantaniello opened this issue 3 years ago • 14 comments

Minimal changes to make fmt::formatted_size constexpr in C++20. Adjust the existing unit test accordingly.

marksantaniello avatar Aug 06 '22 18:08 marksantaniello

CI is failing: https://github.com/fmtlib/fmt/runs/7734651761?check_suite_focus=true

vitaut avatar Aug 08 '22 21:08 vitaut

Seems Clang-11 has some issue with memcpy not being constexpr. Trying to repro but for me clang 11 actually crashes...

marksantaniello avatar Aug 08 '22 22:08 marksantaniello

OK got a repro. I was missing that I needed to use libc++. Will investigate.

marksantaniello avatar Aug 08 '22 23:08 marksantaniello

Seems the problem is here:

https://github.com/fmtlib/fmt/blob/master/include/fmt/format.h#L295-L305

I think Clang 11 supports -std=c++20, but the included libc++ doesn't have __cpp_lib_bit_cast, so we end up trying to use memcpy in a constexpr function.

marksantaniello avatar Aug 09 '22 00:08 marksantaniello

Maybe I can work around this by using __builtin_bit_cast

marksantaniello avatar Aug 09 '22 03:08 marksantaniello

For C++20 constexpr fmt needs a bit_cast. bit_cast requires (https://en.cppreference.com/w/cpp/compiler_support): GCC libstdc++: 11 (_GLIBCXX_RELEASE >= 11, based on: __builtin_bit_cast) Clang libc++: 14 (_LIBCPP_VERSION >= 14000, based on: __builtin_bit_cast) MSVC STL: 19.27

I suggest checking these conditions or __builtin_bit_cast when defining FMT_CONSTEXPR20. cc @vitaut

@marksantaniello, You can enable Github Actions for your fmt fork

phprus avatar Aug 09 '22 07:08 phprus

@phprus

You can enable Github Actions for your fmt fork

Are you saying that there's a way to get all the same test workflows running on my fork?

marksantaniello avatar Aug 09 '22 13:08 marksantaniello

@marksantaniello Yes.

phprus avatar Aug 09 '22 14:08 phprus

Thanks. I'll have to figure do that if I make PRs in the future. The test matrix is pretty large.

Anyway, it looks like the current version using __builtin_bit_cast is passing the checks.

marksantaniello avatar Aug 09 '22 14:08 marksantaniello

Current test matrix does not check: gcc-10 + C++20 (defined FMT_CONSTEXPR20, but not support __builtin_bit_cast) Clang libc++ < 14 + C++20

phprus avatar Aug 09 '22 15:08 phprus

Ah, OK. Maybe I should figure out the workflows now then. I enabled "Actions" but I'm not sure how to clone the checks from here. And then I guess I'd need to add at least two more?

marksantaniello avatar Aug 09 '22 16:08 marksantaniello

Strategies are defined in the .github/workflows/linux.yml file:

https://github.com/fmtlib/fmt/blob/8bd02e93b2d38ce3d69f117623e64e28c6f331cd/.github/workflows/linux.yml#L11-L61

I think for the test you need to add: gcc-9,gcc-10 + C++20

phprus avatar Aug 09 '22 16:08 phprus

FMT_CONSTEXPR20 should definitely not be changed. I suggest making the test conditional on whether __cpp_lib_bit_cast is defined, removing the bit_cast changes and new CI configs (we already have way too many). Then everything that used to work will continue to work and if bit_cast is constexpr and there is C++20 constexpr support then formatted_size will usable in constexpr.

vitaut avatar Aug 09 '22 21:08 vitaut

Looks good but there are some merge conflicts, please rebase.

vitaut avatar Aug 10 '22 02:08 vitaut

Thanks!

vitaut avatar Aug 10 '22 16:08 vitaut