boostorg / boostorg/multiprecision
GCC rejects constexpr operations on cpp_int (> double_limb_type) initialized from a double_limb_type integer
- Dominant language
- C++
- Stars
- 265
- Forks
- 128
- Avg merge
- 4h 48m
- Merged PRs (30d)
- 2
Description
Currently, gcc is rejecting to compile constexpr operations on fixed `cpp_int`s wider than `double_limb_type`. It says that the current initialized field is `m_double_first_limb`, even after we initialize `m_data`:
Here
https://github.com/boostorg/multiprecision/blob/df89bfdef1d7c6d4c142a8f8ef9dbb38286c7122/include/boost/multiprecision/cpp_int.hpp#L583-L588
And here
https://github.com/boostorg/multiprecision/blob/df89bfdef1d7c6d4c142a8f8ef9dbb38286c7122/include/boost/multiprecision/cpp_int.hpp#L776-L781
There's also this one, but it will only be an issue with constexpr dynamic allocations, I can fix it here or I can fix it at my PR #654. I also think the `BOOST_MP_ENDIAN_LITTLE_BYTE` check will not be needed anymore as the split will be explicit as in the other cases
https://github.com/boostorg/multiprecision/blob/df89bfdef1d7c6d4c142a8f8ef9dbb38286c7122/include/boost/multiprecision/cpp_int.hpp#L231-L235
Below is a minimal reproducible example
```cpp
#include
template
inline constexpr auto repro = [] constexpr noexcept {
namespace mp = boost::multiprecision;
using ubits_t = mp::number<
mp::cpp_int_backend,
// also happens for mp::et_on
mp::et_off
>;
ubits_t x = static_cast(0);
// ubits_t x = 0U; // does not fail
// x *= x; // multiplication also fails
x += x;
return x;
}();
// DOES NOT FAIL
// static_assert(repro<128> == 0);
// FAIL
static_assert(repro<129> == 0);
// static_assert(repro<192> == 0);
// static_assert(repro<512> == 0);
```
Here's a [link to compiler explorer](https://godbolt.org/z/38aEe41Tr). You can see that this is GCC only as clang works fine.
The solution is a simple change on how the `cpp_int`s are constructed on the `m_double_first_limb` (initialize `m_data` instead of `m_double_first_limb` on all cases). I can open a PR (with regression tests) if needed (I have a working version here that I used to locate the issue).
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in include/boost/multiprecision/cpp_int.hpp at the constructor cases around lines 231-235, 583-588, and 776-781. Compile the minimal reproducer with GCC and confirm the existing 128-bit case still works while wider fixed cpp_int cases fail. The work is done when the constexpr static_asserts for wider types compile successfully, with regression tests covering the reported initialization and arithmetic cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100