
After a rather difficult debugging session I discovered a feature of the C++ interface shipped with GMP 4.0.1 that is rather questionable. The problem is exemplified by the following snippet:
////////////////////////////////////////////////////////////////////////// #include <gmpxx.h>
typedef struct any_thing* any_pointer;
any_pointer bar();
void foo() { //int i = bar(); // This is flagged as an invalid conversion... mpz_class n = bar(); // ... but this one is happily accepted! } //////////////////////////////////////////////////////////////////////////
As you see, a pointer is erroneously used to initialize an mpz_class object, but this is not and cannot be flagged by the compiler, not even as a warning. The reason is that <gmpxx.h> has a constructor defined as
__gmp_expr(bool b) { mpz_init_set_ui(mp, b); }
and the C++ standard specifies (clause 4.1.2, [conv.bool]) that
An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.
So what happens is that a pointer is converted to true or false and then converted to 1 or 0 and this is what is used to initialize the object. Since this can give rise to bugs that are quite difficult to diagnose, I propose the above constructor is removed altogether, so that the compiler can complain loudly. Notice that qualifying that constructor as `explicit' would not be enough as
mpz_class n = bar();
would be flagged as an error, but
mpz_class n(bar());
would be happily accepted. Removing the constructor would not cause a significant loss in functionality since the rare cases where one wants to do such a thing can be handled in several ways, most of which are more readable and faithful to the actual intention that the examples above.
I have mailed this message to the present list and not to bug-gmp because
a) strictly speaking, this is not a bug; b) other users may benefit from this information.
All the best
Roberto