Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. funny with boost::tribool

funny with boost::tribool

Scheduled Pinned Locked Moved C / C++ / MFC
help
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Robin Imrie
    wrote on last edited by
    #1

    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.

    C C 2 Replies Last reply
    0
    • R Robin Imrie

      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.

      C Offline
      C Offline
      Chris Meech
      wrote on last edited by
      #2

      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]

      R 1 Reply Last reply
      0
      • R Robin Imrie

        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.

        C Offline
        C Offline
        CPallini
        wrote on last edited by
        #3

        Wow, that's interesting.

        Veni, vidi, vici.

        R 1 Reply Last reply
        0
        • C Chris Meech

          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]

          R Offline
          R Offline
          Robin Imrie
          wrote on last edited by
          #4

          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.

          C 1 Reply Last reply
          0
          • R Robin Imrie

            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.

            C Offline
            C Offline
            Chris Meech
            wrote on last edited by
            #5

            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]

            1 Reply Last reply
            0
            • C CPallini

              Wow, that's interesting.

              Veni, vidi, vici.

              R Offline
              R Offline
              Robin Imrie
              wrote on last edited by
              #6

              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.

              C 1 Reply Last reply
              0
              • R Robin Imrie

                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.

                C Offline
                C Offline
                Chris Meech
                wrote on last edited by
                #7

                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]

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups