Posts: 32 / Nickname: cda / Registered: February 11, 2003 0:06 PM
The Safe Bool Idiom
July 30, 2004 8:00 PM
|
This article shows how to validate C++ objects in a boolean context without the usual harmful side effects.
http://www.artima.com/cppsource/safebool.html |
Posts: 1 / Nickname: tox / Registered: August 2, 2004 4:19 AM
Re: The Safe Bool Idiom
August 2, 2004 8:29 AM
|
there appears to be a confusing typo in the article:
class Testable_without_virtual : public safe_bool { it should read: class Testable_without_virtual : public safe_bool<Testable_without_virtual> { |
Posts: 32 / Nickname: cda / Registered: February 11, 2003 0:06 PM
Re: The Safe Bool Idiom
August 3, 2004 3:28 PM
|
Fixed. Thanks. My fault (not the author's).
|
Posts: 1 / Nickname: ghackman / Registered: August 6, 2004 9:48 AM
Re: The Safe Bool Idiom
August 6, 2004 2:16 PM
|
Nice article - thank you. One question though: what's wrong with providing
along with
? |
Posts: 9 / Nickname: bfk / Registered: August 4, 2004 9:28 AM
Re: The Safe Bool Idiom
August 7, 2004 5:16 AM
|
Providing operator! is fine -- but not really necessary, as the implicit conversion to a boolean-testable type already adds support for that operator.
Bjorn |
Posts: 1 / Nickname: ghickman / Registered: August 6, 2004 10:27 AM
Re: The Safe Bool Idiom
August 7, 2004 4:33 PM
|
For some reason, Borland C++ Builder 6 has trouble unless I explicitly provide operator !() const. :(
Thanks again, Greg |
Posts: 3 / Nickname: nathan2 / Registered: August 2, 2004 3:38 AM
Re: The Safe Bool Idiom
August 2, 2004 8:23 AM
|
You mentioned in your article that C++ allows one to delete pointers to const data. What possible reason could the designers have for allowing such an action? Does it allow one to delete const objects as well?
|
Posts: 2 / Nickname: kevlin / Registered: April 25, 2003 3:37 AM
Re: The Safe Bool Idiom
August 25, 2004 5:43 AM
|
> You mentioned in your article that C++ allows one to
> delete pointers to const data. What possible reason could > the designers have for allowing such an action? Does it > allow one to delete const objects as well? Allowing deletion of const data by definition includes deletion of const objects. The simple reason for allowing it is that disposing of an object is not considered to be a non-const operation on that object, and that there would otherwise be no way of getting rid of const objects. Even assuming that the underlying object being pointed were not const at creation, the language still allows the expression new const T, which implies that there must be some reasonable way of getting rid of such objects without resorting to const_cast skulduggery. And then there is the ubiquitous case of being able to declare a local, member or namespace variable const. Such objects have a bounded lifetime and will be properly destroyed at the end of the scope, enclosing object's life or program, so why should dynamically allocated objects be any different? |
Posts: 28 / Nickname: greggwon / Registered: April 6, 2003 1:36 PM
Re: The Safe Bool Idiom
August 3, 2004 7:06 PM
|
> This article shows how to validate C++ objects in a
> boolean context without the usual harmful side effects. Compared to a conversion function to bool, we have avoided the unfortunate overloading issues, and the effects of returning an integral type (making some nonsense constructs legal). We have added the usability that was obscured by operator!, and disabled the potential delete issue with operator void*. Quite impressive! Theres one additional twist that makes the solution complete, and that is to disable comparisons between distinct instances of Testable. With our current implementation, you can write code like this: Testable test; Testable test2; if (test1==test2) {} if (test!=test2) {} Comparisons like the above are not only meaningless; theyre dangerous, because they imply an equivalence relationship that can never exist between different instances of Testable. We need to find a way to disable such nonsensical comparisons. I, regularly design objects where instance equality and value equality differ. It is not unusual for me to use objects where the internal data dictates equality instead of the instances address or other referenced location. I found this article to be a great demonstration of how hard the C++ crowd tries to solve problems that just shouldn't be around. This whole boolean comparison thing falls out of the fact that people still think that it saves time, programmer labor and perhaps memory to write if( ptr ) { ... } instead of just flat out saying what you mean if( ptr != NULL ) { ... } In the Java language design, this whole issue was removed from consideration by demanding an explicit boolean valued expression must be present. Wow, suddenly the problem is completely removed from the programmers radar, and the compiler design is simplified and ... The other thing of course is the fact that there is a basic Object that has a few very important methods on it. One is the equals(Object) method that makes it even easier to deal with the instance equals verses the value equals issue. I'm still really appreciating my choice to use Java and not have to deal with such dangerous and burdensome concepts in a computer language. |
Posts: 9 / Nickname: bfk / Registered: August 4, 2004 9:28 AM
Re: The Safe Bool Idiom
August 7, 2004 5:50 AM
|
> I, regularly design objects where instance equality
> and value equality differ. It is not unusual for > me to use objects where the internal data dictates > equality instead of the instances address or other > referenced location. Well, sure. That's true for all object-oriented languages (although some languages provide access to lower-level details [such as memory location] and some don't). > I found this article to be a great demonstration of how > hard the C++ crowd tries to solve problems that just > shouldn't be around. This whole boolean comparison thing > falls out of the fact that people still think that it > saves time, programmer labor and perhaps memory to write > if( ptr ) { > ... > } > instead of just flat out saying what you mean > if( ptr != NULL ) { > ... > } That's not the end of the story; for example, testing the validity of a stream against NULL is nonsensical, whereas using it as a Boolean type makes perfect sense. (Also, the "C++ crowd" can easily avoid these subtle pitfalls, simply by not using any of the techniques mentioned in the article. Raw pointers can most certainly be tested against NULL without it [although the terser test is also allowed in this fine language!].) > The other thing of course is the fact that there is a > basic Object that has a few very important methods on it. > One is the equals(Object) method that makes it > t even easier to deal with the instance equals > verses the value equals issue. It's not really that hard in C++: SomeClass sc1,sc2; // Equality of objects if (sc1==sc2) {} // Equality of storage location if (&sc1==&sc2) {} > I'm still really appreciating my choice to use Java and > not have to deal with such dangerous and burdensome > concepts in a computer language. For some problems, I agree that there are languages more suitable than C++. On the other hand, the power, expressiveness, beauty, and the language's support for unrestrained creativity are, in my opinion, outstanding virtues of C++ that make me appreciate _my_ choice. As always, your mileage may vary... Bjorn |
Posts: 28 / Nickname: greggwon / Registered: April 6, 2003 1:36 PM
Re: The Safe Bool Idiom
August 15, 2004 5:43 PM
|
> That's not the end of the story; for example, testing the
> validity of a stream against NULL is nonsensical, whereas > using it as a Boolean type makes perfect sense. (Also, the > "C++ crowd" can easily avoid these subtle pitfalls, simply > by not using any of the techniques mentioned in the > article. Raw pointers can most certainly be tested against > NULL without it [although the terser test is also allowed > in this fine language!].) Well, it is a problem in C++ that there are not standard libraries handling I/O streams with all the associated member methods for asking questions like isEof(), availCount() etc. These make much more sense than if( iostream ) { ... } which for old C developers would mean is this initialized. It just makes little sense to keep pressing this programming expression given all the history and confusion that persists. > It's not really that hard in C++: > > SomeClass sc1,sc2; > // Equality of objects > if (sc1==sc2) {} > // Equality of storage location > if (&sc1==&sc2) {} But, then someone has to remember to define the operator overload for the associated types. > For some problems, I agree that there are languages more > suitable than C++. On the other hand, the power, > expressiveness, beauty, and the language's support for > unrestrained creativity are, in my opinion, outstanding > virtues of C++ that make me appreciate _my_ choice. As > always, your mileage may vary... For a lot of people, they get to express nonsensical expressions that make sense to them, but which add any real value to the software system that they are constructing. I'd guess there might be some lazy typing issues, and perhaps some inability to type either due to training or physical issues. I do have sympathy for those that don't like to, or can't type. But, it is an issue that needs to be dealt with for all programming environments. |
Posts: 3 / Nickname: codic / Registered: August 26, 2004 3:49 PM
Re: The Safe Bool Idiom
August 26, 2004 8:21 PM
|
> Well, it is a problem in C++ that there are not standard
> libraries handling I/O streams with all the associated > member methods for asking questions like isEof(), > availCount() etc. Standard C++ provides: bool basic_ios::eof() const; A standard POSIX implementation provides: extern int select (int __nfds, fd_set *__restrict __readfds, It may not be pretty, but the complete functionality of select is missing from Java's standard streams. You need to complicate your design with extra threads to mimic it. Also, InputStream.available()always returns 0 unless overridden by a derived class which often is not the case. > But, then someone has to remember to define the operator > overload for the associated types. Using the & operator on 2 object instances/references to determine if they refer to the same object requires no operator overloading.By default, Java's Object.equals()only returns true if the 2 objects being compared are, in fact, the same instance of an object. You need to implement all class specific value comparisons yourself. By default, C++'s operator== compares each data member in a class so you usually get a sensible object value comparison without having to overload anything.Just the facts. ian. |
Posts: 2 / Nickname: kevlin / Registered: April 25, 2003 3:37 AM
Re: The Safe Bool Idiom
August 27, 2004 0:21 AM
|
> By default, Java's Object.equals() only
> returns true if the 2 objects being compared are, in fact, > the same instance of an object. You need to implement all > class specific value comparisons yourself. > > By default, C++'s operator== compares each > data member in a class so you usually get a sensible > object value comparison without having to overload > anything. > > Just the facts. Or not, as the case might be ;-) By default, C++ does not provide operator== for user-defined types: that task falls to the programmer. For equality, Java defaults to identity equality, C++ defaults to nothing, and C# defaults to identity equality for identity-based objects (of class type) and field-by-field comparison for value-based objects (of struct type). Kevlin |
Posts: 3 / Nickname: codic / Registered: August 26, 2004 3:49 PM
Re: The Safe Bool Idiom
August 27, 2004 4:34 AM
|
> > Just the facts.
> > Or not, as the case might be ;-) Haha! Right you are. Confused operator== with operator=. Thanks for straightening me out. Excuse me while I get this egg off my face. ian |
Posts: 28 / Nickname: greggwon / Registered: April 6, 2003 1:36 PM
Re: The Safe Bool Idiom
August 30, 2004 11:14 AM
|
> > Well, it is a problem in C++ that there are not
> standard > > libraries handling I/O streams with all the associated > > member methods for asking questions like isEof(), > > availCount() etc. > > Standard C++ provides: > bool basic_ios::eof() const; Yes, there is basic_ios, istream, ostream, sstream etc. But I am not enamored by these APIs. They have disconnects and complexities that are just amazing to me to see at such a mature point in the development of this language. Looks like a design by committee where no one was talking (or perhaps even thinking). > A standard POSIX implementation provides: > extern int select (int __nfds, fd_set *__restrict > > It may not be pretty, but the complete functionality of > select is missing from Java's standard> streams. You need to complicate your design with extra > threads to mimic it. Also, > InputStream.available()always returns 0 > unless overridden by a derived class which often is not > the case. Have you looked at Java since 1.0? The nio package provides access to using native select() or poll() implementations on socket and file streams. There are more enhancements in the works I understand for JDK1.6/6.0 > > But, then someone has to remember to define the > operator > > overload for the associated types. > > Using the & operator on 2 object> instances/references to determine if they refer to the > same object requires no operator overloading. But, that is more of that confusing syntax stuff that doesn't provide the user with any good sub-conscience glue. Making users type obj1.equals( obj2 ) is not a bad thing either... > By default, Java's Object.equals()only > returns true if the 2 objects being compared are, in fact, > the same instance of an object. You need to implement all > class specific value comparisons yourself. By default == and .equals() are equivalent for any class that does not override .equals(). In applications where it make sense, you can redefine .equals() to be value based instead of instance based. > By default, C++'s operator== compares each> data member in a class so you usually get a sensible > object value comparison without having to overload > anything. I believe this was pointed out to be in error. Would be interesting to see how that would be implemented without == being assigned to a member method to begin with. |
Posts: 3 / Nickname: codic / Registered: August 26, 2004 3:49 PM
Re: The Safe Bool Idiom
September 3, 2004 5:54 PM
|
> Have you looked at Java since 1.0? The nio package
> provides access to using native select() or poll() > implementations on socket and file streams. Hey, lookie there! I googled for this a couple months ago and found nothing (except a few people saying it couldn't be done). Must have been using crappy search criteria. > But, that is more of that confusing syntax stuff that > doesn't provide the user with any good sub-conscience > glue. Making users type obj1.equals( obj2 ) is not a bad > thing either... I wouldn't call the "address of" operator confusing, but it's all a matter of opinion. > Would be > interesting to see how that would be implemented without > == being assigned to a member method to begin with. The compiler writers have managed to do it with implicitly defined operator= and copy constructors. I don't think it's too much of a stretch to apply similar member traversal logic to equality comparisons, but aparently some one did. Perhaps the answer lies in the ARM. Well, shame on me for not knowing my tools. I obviously don't know either language well enough to effectively argue the finer points of either one in a public forum. But I do know that you use the right tool for the right job. Sometimes the right tool is C++ (like it or not), and articles like this make better programmers out of all of us. ian. |
Posts: 1 / Nickname: sekmu / Registered: March 30, 2009 1:59 PM
Re: The Safe Bool Idiom
March 30, 2009 7:19 PM
|
A word of warning, and a question for if anyone has encountered and/or has a solution for this issue (other than the obvious "don't allow this code").
If you (already) have an explicit conversion to a pointer type other than bool_type, the compiler may very well choose the non-bool_type, resulting in unexpected behavior. example crashy:
|
Posts: 1 / Nickname: joem / Registered: October 13, 2010 6:02 AM
Re: The Safe Bool Idiom
October 13, 2010 11:04 AM
|
Is this code copyright restricted? Is there a license for reuse of this code?
|