[Gmp-commit] /var/hg/gmp: Do not use mp directly in mpz_class
mercurial at gmplib.org
mercurial at gmplib.org
Mon Apr 18 16:21:48 CEST 2022
details: /var/hg/gmp/rev/88e4445a72d1
changeset: 18347:88e4445a72d1
user: Marc Glisse <marc.glisse at inria.fr>
date: Mon Apr 18 16:19:20 2022 +0200
description:
Do not use mp directly in mpz_class
This is the difference between f and g in the following,
where gcc generates "return 1;" for f and not for g.
The aliasing is caused by the functions get_num and get_den
in mpq_class.
struct mpz_struct { int i; };
typedef mpz_struct mpz_t[1];
struct mpq_struct { mpz_struct num, den; };
typedef mpq_struct mpq_t[1];
struct mpz_class { mpz_t mp; };
struct mpq_class { mpq_t mp; };
int f(mpq_class*q, mpz_class*z){
q->mp->num.i = 1;
z->mp->i = 2;
return q->mp->num.i;
}
int g(mpq_class*q, mpz_class*z){
q->mp->num.i = 1;
int*p=&z->mp->i;
*p = 2;
return q->mp->num.i;
}
diffstat:
ChangeLog | 4 ++++
gmpxx.h | 17 ++++++++++-------
2 files changed, 14 insertions(+), 7 deletions(-)
diffs (66 lines):
diff -r 541600d84118 -r 88e4445a72d1 ChangeLog
--- a/ChangeLog Mon Apr 18 09:09:50 2022 +0200
+++ b/ChangeLog Mon Apr 18 16:19:20 2022 +0200
@@ -1,3 +1,7 @@
+2022-04-18 Marc Glisse <marc.glisse at inria.fr>
+
+ * gmpxx.h (mpz_class): Do not use mp directly.
+
2022-03-18 Marco Bodrato <bodrato at mail.dm.unipi.it>
* tests/mpz/t-lucm.c: Remove an unused var.
diff -r 541600d84118 -r 88e4445a72d1 gmpxx.h
--- a/gmpxx.h Mon Apr 18 09:09:50 2022 +0200
+++ b/gmpxx.h Mon Apr 18 16:19:20 2022 +0200
@@ -1580,7 +1580,7 @@
void assign_ui(unsigned long l)
{
if (__GMPXX_CONSTANT_TRUE(l == 0))
- mp->_mp_size = 0;
+ __get_mp()->_mp_size = 0;
else
mpz_set_ui(mp, l);
}
@@ -1634,7 +1634,7 @@
__gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
#if __GMPXX_USE_CXX11
__gmp_expr(__gmp_expr &&z) noexcept
- { *mp = *z.mp; mpz_init(z.mp); }
+ { *__get_mp() = *z.__get_mp(); mpz_init(z.mp); }
#endif
template <class T>
__gmp_expr(const __gmp_expr<mpz_t, T> &expr)
@@ -1666,7 +1666,8 @@
~__gmp_expr() { mpz_clear(mp); }
- void swap(__gmp_expr& z) __GMPXX_NOEXCEPT { std::swap(*mp, *z.mp); }
+ void swap(__gmp_expr& z) __GMPXX_NOEXCEPT
+ { std::swap(*__get_mp(), *z.__get_mp()); }
// assignment operators
__gmp_expr & operator=(const __gmp_expr &z)
@@ -1728,7 +1729,7 @@
// bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
#if __GMPXX_USE_CXX11
- explicit operator bool() const { return mp->_mp_size != 0; }
+ explicit operator bool() const { return __get_mp()->_mp_size != 0; }
#endif
// member operators
@@ -1896,9 +1897,11 @@
// conversion functions
- // casting a reference to an mpz_t to mpz_class & is a dirty hack,
- // but works because the internal representation of mpz_class is
- // exactly an mpz_t
+ // casting a reference to an mpz_t to mpz_class & is a dirty hack.
+ // It kind of works because the internal representation of mpz_class is
+ // exactly an mpz_t, but compilers are allowed to assume that mpq_class
+ // and mpz_class do not alias... In mpz_class, we avoid using mp directly,
+ // to reduce the risks of such problematic optimizations.
const mpz_class & get_num() const
{ return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
mpz_class & get_num()
More information about the gmp-commit
mailing list