Hello, This is just a C++ nitpick, but operator bool() is often considered harmful because of the plethora of implicit conversions (bool->int being the worst of these implicit conversions, IMHO). I'm not suggesting that operator bool() be removed from relational, but instead replace it with a safer construct. Within the Boost C++ libraries (http://www.boost.org), we've adopted a "safe_bool" conversion using of a pointer-to-member function. The trick can be illustrated concisely: // Add to class relational private: struct dummy { void nonnull() {}; }; typedef void (dummy::*safe_bool)(); safe_bool make_safe_bool(bool cond) const { return cond? &dummy::nonnull : 0; } Then in relational::operator safe_bool() const, whereever there is a "return <bool-expression>", it should be replaced with "return make_safe_bool(<bool-expression>)". The use of the pointer-to-member function eliminates implicit conversions, but the relational class can still be used in a boolean context (since it is evaluated as "is the pointer-to-member function null?"). All meaningless operations that are allowed by a "bool" conversion except for == and != are eleminated by this "safe_bool". I can submit a patch against CVS if needed. Doug Gregor gregod@cs.rpi.edu
On Wed, 14 Nov 2001, Douglas Gregor wrote:
Hello, This is just a C++ nitpick, but operator bool() is often considered harmful because of the plethora of implicit conversions (bool->int being the worst of these implicit conversions, IMHO). I'm not suggesting that operator bool() be removed from relational, but instead replace it with a safer construct. Within the Boost C++ libraries (http://www.boost.org), we've adopted a "safe_bool" conversion using of a pointer-to-member function. The trick can be illustrated concisely:
// Add to class relational private: struct dummy { void nonnull() {}; };
typedef void (dummy::*safe_bool)();
safe_bool make_safe_bool(bool cond) const { return cond? &dummy::nonnull : 0; }
Then in relational::operator safe_bool() const, whereever there is a "return <bool-expression>", it should be replaced with "return make_safe_bool(<bool-expression>)".
The use of the pointer-to-member function eliminates implicit conversions, but the relational class can still be used in a boolean context (since it is evaluated as "is the pointer-to-member function null?"). All meaningless operations that are allowed by a "bool" conversion except for == and != are eleminated by this "safe_bool".
I can submit a patch against CVS if needed.
Can you please email that patch? (I'm still trying to grok whether this breaks compatibilities. Binary yes, I guess.) Regards -richy. -- Richard Kreckel <Richard.Kreckel@Uni-Mainz.DE> <http://wwwthep.physik.uni-mainz.de/~kreckel/>
On Wednesday 14 November 2001 10:38 am, you wrote:
Can you please email that patch? (I'm still trying to grok whether this breaks compatibilities. Binary yes, I guess.)
I've attached the patch against current CVS. It will break binary compatibility on some platforms. There is also a source compatibility break if one uses: relation r = ...; if (r == true) ... If that's a concern, it can be fixed with a few overloads of operator== and operator!= for (relation,bool) and (bool,relation). Doug
On Wed, 14 Nov 2001, Douglas Gregor wrote:
I've attached the patch against current CVS. It will break binary compatibility on some platforms.
What's the criterion for such a platform? (It sure breaks on Linux-x86/GCC.) Cheers -richy. -- Richard B. Kreckel <Richard.Kreckel@Uni-Mainz.DE> <http://wwwthep.physik.uni-mainz.de/~kreckel/>
On Friday 16 November 2001 11:46 am, you wrote:
On Wed, 14 Nov 2001, Douglas Gregor wrote:
I've attached the patch against current CVS. It will break binary compatibility on some platforms.
What's the criterion for such a platform? (It sure breaks on Linux-x86/GCC.)
I can guess at what the criterion would be for it to _not_ break on a given platform: 1) sizeof(bool) == sizeof(pointer-to-member-function) 2) a NULL pointer-to-member has integral value 0 I would guess that the first condition does not hold for Linux-x86/GCC. I seem to recall that pointers-to-members of polymorphic classes are "fat", because they need to carry some run-time type information with them to deal with the possibilities of multiple/virtual inheritance. Doug
On Fri, 16 Nov 2001, Douglas Gregor wrote:
I can guess at what the criterion would be for it to _not_ break on a given platform: 1) sizeof(bool) == sizeof(pointer-to-member-function) 2) a NULL pointer-to-member has integral value 0
I would guess that the first condition does not hold for Linux-x86/GCC. I seem to recall that pointers-to-members of polymorphic classes are "fat", because they need to carry some run-time type information with them to deal with the possibilities of multiple/virtual inheritance.
Questions of sizeof() aside, I guess it can't work at all because binaries want `GiNaC::relational::operator bool(void) const' which the poor linker cannt whip up fast enough... :-) Cheers -richy. -- Richard B. Kreckel <Richard.Kreckel@Uni-Mainz.DE> <http://wwwthep.physik.uni-mainz.de/~kreckel/>
participants (2)
-
Douglas Gregor
-
Richard B. Kreckel