The C++ interface implicitly converts rationals to integers

Gabriel Dos Reis gdr at integrable-solutions.net
Sun Nov 20 04:23:41 CET 2005


Roberto Bagnara <bagnara at cs.unipr.it> writes:

| Hi there.
| 
| The program
| 
| #include <gmpxx.h>
| #include <iostream>
| 
| using namespace std;
| 
| void foo(const mpz_class& i) {
|    cout << "foo::i = " << i << endl;
| }
| 
| int main() {
|    mpq_class r(3, 4);
|    cout << "main::r = " << r << endl;
|    foo(r);
|    return 0;
| }
| 
| prints
| 
| main::r = 3/4
| foo::i = 0
| 
| This shows that the C++ interface of GMP defines an implicit constructor
| for mpz_class that takes an mpq_class object and (silently) truncates it.
| It is very bad practice for such a constructor to be implicit as this can
| result in bugs that are very difficult to diagnose.  Of course I am not
| questioning the need for such a conversion: I simply think that truncation
| should only be performed when explicitly requested.
| All the best,

In the version of GMP coming with the GNU/Linux distribution I'm
using, there are: 

   typedef __gmp_expr<__gmpz_value, __gmpz_value> mpz_class;
   // ...
   typedef __gmp_expr<__gmpq_value, __gmpq_value> mpq_class;

and further (in the definition of the explicit specialization for mpz_class)

  template <class T, class U>
  __gmp_expr(const __gmp_expr<T, U> &expr)
  { mpz_init(mp); __gmp_set_expr(mp, expr); }

I believe that is the constructor at fault -- it should be explicit.


I reckon the C++ interface to GMP is highly influenced by my
implementation of valarray for GNU libstdc++, but I'm not sure I have
such cases for the valarray implementation.

-- Gaby


More information about the gmp-discuss mailing list