Questionable feature of the C++ interface (GMP 4.0.1)
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 -- Prof. Roberto Bagnara Computer Science Group Department of Mathematics, University of Parma, Italy http://www.cs.unipr.it/~bagnara/ mailto:bagnara@cs.unipr.it
Roberto Bagnara <bagnara@cs.unipr.it> writes:
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.
Sounds good to me. I guess if someone actually wants to initialize from a bool they can cast to an int first.
participants (2)
-
Kevin Ryde -
Roberto Bagnara