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