boostorg / boostorg/multiprecision

GCC rejects constexpr operations on cpp_int (> double_limb_type) initialized from a double_limb_type integer

Open
#768 4 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.