funny with boost::tribool
-
can any one explain why this code...
#include <boost\logic\tribool.hpp>
using namespace boost;
using namespace std;tribool test1();
tribool test2();int _tmain(int argc, _TCHAR* argv[])
{
if( !test1() || !test2() )
cout << "test failed" << endl;return 0;
}
tribool test1()
{
cout << "test1" << endl;
return true;
}tribool test2()
{
cout << "test2" << endl;
return false;
}gives the following output.. test2 test1 test failed According to the documentation on the || operator the
The operands of logical-AND and logical-OR expressions are evaluated from left to right. If the value of the first operand is sufficient to determine the result of the operation, the second operand is not evaluated. This is called "short-circuit evaluation." There is a sequence point after the first operand. See Sequence Points for more information.
I fixed the "bug" by changing my if statement to
if( !static_cast<bool>(test1()) || !static_cast<bool>(test2()) )
I did notice in the disassembly that the boost function boost::logic::operator|| was being called and wonder if this what was effecting my logic. Thanks in advance
Thanks, Robin.
-
can any one explain why this code...
#include <boost\logic\tribool.hpp>
using namespace boost;
using namespace std;tribool test1();
tribool test2();int _tmain(int argc, _TCHAR* argv[])
{
if( !test1() || !test2() )
cout << "test failed" << endl;return 0;
}
tribool test1()
{
cout << "test1" << endl;
return true;
}tribool test2()
{
cout << "test2" << endl;
return false;
}gives the following output.. test2 test1 test failed According to the documentation on the || operator the
The operands of logical-AND and logical-OR expressions are evaluated from left to right. If the value of the first operand is sufficient to determine the result of the operation, the second operand is not evaluated. This is called "short-circuit evaluation." There is a sequence point after the first operand. See Sequence Points for more information.
I fixed the "bug" by changing my if statement to
if( !static_cast<bool>(test1()) || !static_cast<bool>(test2()) )
I did notice in the disassembly that the boost function boost::logic::operator|| was being called and wonder if this what was effecting my logic. Thanks in advance
Thanks, Robin.
Unless I'm missing something, the if check should resolve to ( false || true ) which resolves to true and so the test failed should be the output. :) Now I see what I was missing. :-O You are wondering why the call to test2 occurs first? My guess would be that the documentation is only for the intrinsic types of the language and the "tribool" may implement it's own || operator.
Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
-
can any one explain why this code...
#include <boost\logic\tribool.hpp>
using namespace boost;
using namespace std;tribool test1();
tribool test2();int _tmain(int argc, _TCHAR* argv[])
{
if( !test1() || !test2() )
cout << "test failed" << endl;return 0;
}
tribool test1()
{
cout << "test1" << endl;
return true;
}tribool test2()
{
cout << "test2" << endl;
return false;
}gives the following output.. test2 test1 test failed According to the documentation on the || operator the
The operands of logical-AND and logical-OR expressions are evaluated from left to right. If the value of the first operand is sufficient to determine the result of the operation, the second operand is not evaluated. This is called "short-circuit evaluation." There is a sequence point after the first operand. See Sequence Points for more information.
I fixed the "bug" by changing my if statement to
if( !static_cast<bool>(test1()) || !static_cast<bool>(test2()) )
I did notice in the disassembly that the boost function boost::logic::operator|| was being called and wonder if this what was effecting my logic. Thanks in advance
Thanks, Robin.
-
Unless I'm missing something, the if check should resolve to ( false || true ) which resolves to true and so the test failed should be the output. :) Now I see what I was missing. :-O You are wondering why the call to test2 occurs first? My guess would be that the documentation is only for the intrinsic types of the language and the "tribool" may implement it's own || operator.
Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
Looking further in to the tribool header file there is an overload for the || operator (and && operator) I am yet to look further into it to work out which parameter is which in the overload. I would of thought that an overridden || operator would or at least should work in the same way as it does with intrinsic types.
Thanks, Robin.
-
Looking further in to the tribool header file there is an overload for the || operator (and && operator) I am yet to look further into it to work out which parameter is which in the overload. I would of thought that an overridden || operator would or at least should work in the same way as it does with intrinsic types.
Thanks, Robin.
The parsing and evaluation of the if construct probably implements some kind of LIFO stack and that is why you see test2 called before test1. But it is odd behaviour. :)
Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
-
It is yes and it was very confusing as I had similar code relating to comms where I was doing something like:
if( !unit.Connected() || !unit.IsTypeA()
{
PrintFailMessage( "Failed to connect" );
}and this worked just fine, but due to other reasons I changed my return type for the functions to boost::tribool and all of a sudden the IsTypeA() function was getting called first. Had me going for ages.
Thanks, Robin.
-
It is yes and it was very confusing as I had similar code relating to comms where I was doing something like:
if( !unit.Connected() || !unit.IsTypeA()
{
PrintFailMessage( "Failed to connect" );
}and this worked just fine, but due to other reasons I changed my return type for the functions to boost::tribool and all of a sudden the IsTypeA() function was getting called first. Had me going for ages.
Thanks, Robin.
Robin Imrie wrote:
all of a sudden the IsTypeA() function was getting called first
Thats a good reason for changing the code to
bool bConnected = unit.Connected();
bool bIsTypeA = unit.IsTypeA();if ( !bConnected || !bIsTypeA )
{
PinrFailMessage( "Failed to connect" );
}This will ensure that the call to Connected is always made first, regardless of what type is used for the return value. :)
Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]