boost::tribool "if ( someTriboolVar == indeterminate )" semantics is confusing
I started using tribool recently. I just discovered that I was using it incorrectly. I had code that did something like: tribool triboolVar1 = indeterminate; if ( triboolVar1 == indeterminate ) { cout << "triboolVar1 is indeterminate" << endl; } else { cout << "triboolVar1 is NOT indeterminate" << endl; } I was expecting this to print "triboolVar1 is indeterminate". However it prints "triboolVar1 is NOT indeterminate". I ended up looking through "include/boost/logic/tribool.hpp" and after a bit of head scratching, I think I understand why this doesn't do what I expect: The above "if" line is "really" (pseudo-code): if ( operator==(tribool triboolVar1,tribool indeterminate) ) { where operator== returns a tribool, and (I think) tribool::operator safe_bool() const { return value == true_value? &dummy::nonnull : 0; } is used to turn the tribool into a bool. And give that operator== says: ... if (indeterminate(x) || indeterminate(y)) return indeterminate; ... Then clearly no matter what the value of triboolVar1 is, the "if" code will be false. I haven't had any schooling in what (I'm assuming) might be called something like "Multi-Level-Logic", but: Shouldn't an "indeterminate" value equal another "indeterminate" value? -- Peter Hackett Member of Technical Staff IC Manage http://icmanage.com phone (408) 358-8191 x6012
Hello, Peter,
Sure, it is the same logic as when comparing std::numeric_limits<float>::quiet_NaN() values.
Any expression involving indeterminate value should give indeterminance, any comparison should yield falseness, i.e. ((nan==nan) == false) and ((nan!=nan) == false) at the same time.
In other words, you can't say two values to be the same if any (or both) are indeteminate. Equally, you can't say they aren't.
P.S. I sometimes use boost::optional<bool> to get a kind of tri-state value. That works without such surprises.
Best regards,
Fedor Trushkin
06.03.2014, 18:02, "Peter Hackett"
I started using tribool recently. I just discovered that I was using it incorrectly.
I had code that did something like:
tribool triboolVar1 = indeterminate;
if ( triboolVar1 == indeterminate ) { cout << "triboolVar1 is indeterminate" << endl; } else { cout << "triboolVar1 is NOT indeterminate" << endl; }
I was expecting this to print "triboolVar1 is indeterminate". However it prints "triboolVar1 is NOT indeterminate".
I ended up looking through "include/boost/logic/tribool.hpp" and after a bit of head scratching, I think I understand why this doesn't do what I expect:
The above "if" line is "really" (pseudo-code):
if ( operator==(tribool triboolVar1,tribool indeterminate) ) {
where operator== returns a tribool, and (I think)
tribool::operator safe_bool() const { return value == true_value? &dummy::nonnull : 0; }
is used to turn the tribool into a bool.
And give that operator== says:
... if (indeterminate(x) || indeterminate(y)) return indeterminate; ...
Then clearly no matter what the value of triboolVar1 is, the "if" code will be false.
I haven't had any schooling in what (I'm assuming) might be called something like "Multi-Level-Logic", but:
Shouldn't an "indeterminate" value equal another "indeterminate" value?
-- Peter Hackett Member of Technical Staff IC Manage http://icmanage.com phone (408) 358-8191 x6012
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 03/06/2014 03:16 PM, Фёдор Трушкин wrote:
P.S. I sometimes use boost::optional<bool> to get a kind of tri-state value. That works without such surprises.
And fwiw it might use less memory. The simple optional<bool> stores an additional bool to your value, whereas tribool stores an enum that might be bigger than sizeof(bool)*2. At least that's what #7659 [0] says. Norbert [0] https://svn.boost.org/trac/boost/ticket/7659 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBAgAGBQJTGJHRAAoJEN1BMR2v0jNaKYwP/2SCNks2gpIpSznx0DSVYFav DC+LpV5lN5/uB6iI+UEwQC1Am51dJbGHHtuTtOgPWuZbJc+4mXeZcTD+8+T8yulY dvDAPMS42Xbut+XmKoU0yV3nrOhVcsEEHpQxBaLaiBP5KQgN27dnqPv71FwlIpt8 Zbuakiy+oaoKzZ4maObXxo7Hlw4JySZvC/H6vXtDDeRDoS0DFm+SfnbLixCmiKCv 9iH318cMgyF92i5ihuBTj7USPud8c2kedRXKaPhzDy+LH2gSwMEzQgOnAEJZzVD7 hLmyC0PS3jKCsTS6cCXBcpwtENZIB0jp1GSlg/3KZvlB0AeEs6g8doytifsDHWRJ +ABLwPGkLg1+b3O5Bh+OxQgrlwIeBu6S4jb7ZgJ2G/kbXd8Oo5kum7/oeZsSFqRn bFienJV85Th99hp/55bPbw5mnRKnMSqyfGEZiH4cd/IJtWuCA+DGW3c9hslz+bTJ RA6uKRHRCDje44M7PTZv7QPn0mIH9J4n8ti+zgs0yv2LcebE9Kuf9WmZrUZPFW5R U0jf85qSs15n2uIzhgQjW8MtzUCs+SyWoRBLBw1YZXHLqladgavhSDlL0sjKdo5w o9hfQlcdWMziu5kgr6Xq6m9L1ecqHpWqN63YbeKv1fpwyghUd1vsREAPEEASMui5 Ibsiz5SYm8wlCGU0bkiY =3CY2 -----END PGP SIGNATURE-----
On 6/03/2014 17:06, Quoth Peter Hackett:
I had code that did something like:
tribool triboolVar1 = indeterminate;
if ( triboolVar1 == indeterminate ) { cout << "triboolVar1 is indeterminate" << endl; } else { cout << "triboolVar1 is NOT indeterminate" << endl; }
I was expecting this to print "triboolVar1 is indeterminate". However it prints "triboolVar1 is NOT indeterminate".
http://www.boost.org/doc/libs/1_55_0/doc/html/tribool/tutorial.html#idp22516... Shows the correct way to test for an indeterminate value. I thought there was a truth-table for operator== on that page too, but apparently not. Maybe I'm thinking of a different library that had a similar class.
Shouldn't an "indeterminate" value equal another "indeterminate" value?
No, they're like database NULLs. They're never equal to anything, not even themselves. (Since, after all, two things that are unknown by definition cannot be known to equal each other.)
participants (5)
-
Gavin Lambert
-
Norbert Wenzel
-
Peter Hackett
-
Rainer Deyke
-
Фёдор Трушкин