The following code works fine (compiles, assert statement gives true) under Linux/Debian (g++ 10.2), but refuses to work under Windows (mingw64 g++ 12.2.0). It's basically just supposed to assign UINT64_MAX
to a mpf_class
from the gmp library, but it seems gmp's mpf_class
defines no constructor and no operators for uint64_t
, which is unsigned long long int in the windows environment I'm trying to work with here. I bet there is a simple workaround I'm not seeing right now, because it's friday and late, correct?
#include <gmpxx.h> // link with gmp + gmpxx
#include <string>
/// Helper to convert mpf_class to std::string
[[nodiscard]] inline std::string mpf_class_to_str(const mpf_class& num) {
mp_exp_t exponent(1);
return num.get_str(exponent, 10);
}
int main() {
mpf_class y = UINT64_MAX; // defined in my mingw64 as 0xffffffffffffffffULL
// ^
// | adding no cast -> compile error
// adding (unsigned int) cast -> compiles, but assertion below false
// adding (uint64_t) cast -> compile error
y *= UINT64_MAX; // UINT64_MAX²
assert(mpf_class_to_str(y) == "340282366920938463426481119284349108225");
}
The compile error g++ gives me is:
error: conversion from 'long long unsigned int' to 'mpf_class' is ambiguous
31 | mpf_class y = UINT64_MAX;
| ^~~~~~~~~~
and then it lists all candidates, which basically are (taken from gmpxx.h
instead of the error log):
#define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS \
__gmp_expr(signed char c) { init_si(c); } \
__gmp_expr(unsigned char c) { init_ui(c); } \
__gmp_expr(signed int i) { init_si(i); } \
__gmp_expr(unsigned int i) { init_ui(i); } \
__gmp_expr(signed short int s) { init_si(s); } \
__gmp_expr(unsigned short int s) { init_ui(s); } \
__gmp_expr(signed long int l) { init_si(l); } \
__gmp_expr(unsigned long int l) { init_ui(l); } \
__gmp_expr(float f) { init_d(f); } \
__gmp_expr(double d) { init_d(d); }
If I manipulate that header adding the line __gmp_expr(unsigned long long int l) { init_ui(l); }
all is well except this is too dirty of a fix even for me.