Thread: How is && evaluated

  1. #1
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853

    How is && evaluated

    I have seen this code often
    Code:
    if (obj != NULL && obj->var != 0)
    {
       ...
    }\
    and I am wondering if it would start from left to right guaranteed?
    Personally I always write this as
    Code:
    if (obj != NULL)
    {
      if (obj->var != 0)
      {
           ...
       }
    }
    but I am not sure if the above is necessary. I believe that it can start from left or from right depending the compiler, so you have to use multiple ifs. Am I correct?

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by C_ntua View Post
    I have seen this code often
    Code:
    if (obj != NULL && obj->var != 0)
    {
       ...
    }\
    and I am wondering if it would start from left to right guaranteed?
    yes, as well as ||

    Evaluation is going left to right and stops as soon as final result can be 100% guaranteed.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Jun 2010
    Posts
    15
    from what i read in Tutorials and im learning rignt now, this is how Boleans priority are .
    see here and u can use "()"
    eg.:
    if ( ( ( ( obj != NULL ) && ) obj->var != 0 ) )
    {
    ...
    }\

    its ugly but this way u can be perfectly sure it goes from what way u want it to go.
    Last edited by Flo; 06-25-2010 at 12:51 PM.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by Flo View Post
    from what i read in Tutorials and im learning rignt now, this is how Boleans priority are .
    see here and u can use "()"
    eg.:
    Code:
    if ( ( ( ( obj != NULL ) && ) obj->var != 0 ) )
    {
       ...
    }\
    its ugly but this way u can be perfectly sure it goes from what way u want it to go.
    Uhm... maybe you should read some more tutorials yourself :P. Because, no, that's not legal.

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by Flo View Post
    from what i read in Tutorials
    ...
    its ugly but this way u can be perfectly sure it goes from what way u want it to go.
    the direction it goes while evaluating expression tells nothing about when it stops...
    && (logical and) stops as soon as possible

    & (binary and) goes all way till the end even if the final value is determined already on the first step
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Registered User
    Join Date
    Jun 2010
    Posts
    15
    Quote Originally Posted by EVOEx View Post
    Uhm... maybe you should read some more tutorials yourself :P. Because, no, that's not legal.
    ofcourse is not legal && didnt have with what to compare to. my bad .

    i gues this should be legal
    Code:
    if ( ( ( obj != NULL ) && obj->var ) != 0 )
    {
       ...
    }\
    or for what was intended this code i think this should be more apropiate
    Code:
    if ( ( obj != NULL ) && ( obj->var != 0 ) )
    {
       ...
    }\
    in this form it doesent realy matter if it starts from left or right.

    i typed to fast and made a big mistake pff i need to be carefull wile writhing code.ty for poiting that .
    Last edited by Flo; 06-25-2010 at 02:11 PM.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Flo, you addressed EVOEx's point but you missed vart's point. Let us change your last code snippet to:
    Code:
    if ( ( obj != NULL ) & ( obj->var != 0 ) )
    {
        // ...
    }
    Now, order of evaluation is implementation defined. Therefore, whether ( obj != NULL ) is evaluated before ( obj->var != 0 ) is implementation defined. But this is not so for:
    Code:
    if ( ( obj != NULL ) && ( obj->var != 0 ) )
    {
        // ...
    }
    As has been stated, it is guaranteed that ( obj != NULL ) will be evaluated before ( obj->var != 0 ), and there is a sequence point in between these subexpression evaluations.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Nov 2007
    Posts
    46
    It should also be noted that if you overload the && or || operator(s) for a type (or they are overloaded for a type provided by a library, for example) these will not short circuit, and so both the left and right hand sides of the expression will be evaluated. I've also seen it recommended in more than one place that you don't overload these two operators, because you don't expect this behavior.

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by JacobN View Post
    these will not short circuit, and so both the left and right hand sides of the expression will be evaluated.
    No. If the first statement in an AND'd expression is false, the subsequent statements are not evaluated at all. This means it is safe to do this (consider "var" as an object or struct pointer), which is a pretty common way to catch a potential runtime (out of bounds) error:
    Code:
    if ((var) && (var.x == 12))
    If var is NULL, evaluating var.x would be a runtime error and crash the program, because a NULL object/pointer could not possible have a member "x". However, that's not what happens: var.x will only be checked if (var) is true.

    [edit] I think I read your post wrong -- you are saying this normative behaviour will not work if you overload && ? Looks like the C++ FAQ agrees -- thanks for the info JacobN.
    Last edited by MK27; 06-25-2010 at 02:33 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    MK27, JacobN is correct because of the condition "if you overload the && or || operator(s) for a type".
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by Flo;956217
    [code
    if ( ( obj != NULL ) && ( obj->var != 0 ) )
    {
    ...
    }\
    [/code]
    in this form it doesent realy matter if it starts from left or right.

    i typed to fast and made a big mistake pff i need to be carefull wile writhing code.ty for poiting that .
    Maybe you should think even more before you type because, yes, it still matters whether it's evaluated from left to right, as if obj == NULL then obj->var is wrong and probably make the program crash...

    And as stated three times before already: && IS evaluated from left to right. So your "tricks" to make it be evaluated from left to right (that are wrong), are useless.

    Because even:
    Code:
    a = (expression1) + expression2;
    Doesn't make expression1 be executed before expression2. The compiler may still choose to execute expression2, then expression1, and then take the sum.

    Of course, as && is executed from left to right, that's not the case here. So your "tricks" will really do nothing at all.


    Edit: who ever overloads the operator && anyways? I can't think of any situation it would make sense...
    Last edited by EVOEx; 06-25-2010 at 02:35 PM.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by EVOEx
    Edit: who ever overloads the operator && anyways? I can't think of any situation it would make sense...
    I think Boost.Spirit did/does, but then it is one of those special case libraries.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Nov 2007
    Posts
    46
    Quote Originally Posted by laserlight View Post
    I think Boost.Spirit did/does, but then it is one of those special case libraries.
    Indeed the "Classic" version does.

    And I know it's kind of unusual to overload those operators, I can't even think of a case where it would make sense either, but that doesn't keep people from doing things that doesn't make sense. I'm sure that following forums online you've all seen your share of things that didn't make sense. But I figured I would mention it anyway, because it's not what most people expect to happen when you overload that operator?

  14. #14
    Registered User
    Join Date
    Jun 2010
    Posts
    15
    Quote Originally Posted by EVOEx View Post
    Maybe you should think even more before you type because, yes, it still matters whether it's evaluated from left to right, as if obj == NULL then obj->var is wrong and probably make the program crash...
    yup ur right, i didnt read it right, and so i missed that var is from obj so if obj is null that means var doesent exist . my bad again .

    Quote Originally Posted by EVOEx View Post
    And as stated three times before already: && IS evaluated from left to right. So your "tricks" to make it be evaluated from left to right (that are wrong), are useless.

    Because even:
    Code:
    a = (expression1) + expression2;
    Doesn't make expression1 be executed before expression2. The compiler may still choose to execute expression2, then expression1, and then take the sum.

    Of course, as && is executed from left to right, that's not the case here. So your "tricks" will really do nothing at all.
    If "tricks" are so useles and so wrong then how about using "tricks" like this ?
    Code:
        a = ( 10 + 5) *  10 - 5;           //= 145
    is same as : ?
        a =   10 + 5  * (10 - 5);          //= 35
    
     a = expresion1   *   expresion2;        //= result
    so what im trying to say is that you can say to compiler i want to check from what side i want not from what side compiler wants .... :P
    eg.:
    Code:
    if (obj != NULL && obj->var != 0)
    {
       ...
    }\
    like most said and i gues they are not wrong
    && takes (obj != NULL) and compares with (obj->var != 0)

    or
    Code:
    if (      obj != ( NULL && ( obj->var != 0 ) )         )
    {
       ...
    }\
    obj != to && that takes (NULL) and compares with (obj->var != 0)

    ofcourse is not good to do like this for this particular case.
    but im trying to say u can shout to compiler that you want that to be done in your way not how compiler wants ( Control compiler dont let compiler to do what other set him to do)

    i learned today 2lessons Read,Write more carefull :P (i gues i should hit the books on reading,wrighting )
    I hate BOX thinking. I love to think everying can be done like i want.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Flo
    so what im trying to say is that you can say to compiler i want to check from what side i want not from what side compiler wants ....
    Or in more technical terms, you can use parentheses for grouping rather than relying on other precedence rules.

    The point is, order of evaluation and precedence/grouping are two different things (though they are related), hence talking about the use of parentheses does not answer C_ntua's question.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Switch/Case using && != and ||?
    By Kespoosh in forum C++ Programming
    Replies: 6
    Last Post: 03-15-2003, 11:24 PM
  2. Radeon VE 32MB && OpenGL?
    By RoD in forum Tech Board
    Replies: 21
    Last Post: 02-09-2003, 09:10 AM
  3. Replies: 2
    Last Post: 01-13-2003, 01:28 PM
  4. dual-processor + pthreads && signals
    By rotis23 in forum Linux Programming
    Replies: 0
    Last Post: 11-08-2002, 10:54 AM
  5. Muliplayer && Winsock
    By face_master in forum Game Programming
    Replies: 1
    Last Post: 10-08-2002, 06:42 AM