Thread: Bit of confusion with if?

  1. #1
    60% Braindead
    Join Date
    Dec 2005
    Posts
    379

    Bit of confusion with if?

    Ok, I'm wondering what this will do.

    Code:
    int x=1, b=2;
    
    if(x == 1 && b == 2 || x == 2 && b == 2) {
     //actions;
    }
    Will the actions execute? Does c++ consider ands before ors, or vice versa?
    Code:
    Error W8057 C:\\Life.cpp: Invalid number of arguments in function run(Brain *)

  2. #2
    Registered User
    Join Date
    Mar 2004
    Posts
    494
    && are evaluated before || , in this case actions will exec.

    && will exec when both expressions are true, but || will exec when 1 of the expressions is true.
    Last edited by InvariantLoop; 03-06-2006 at 11:32 PM.
    When no one helps you out. Call google();

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Actually, I dont see why you cant work it out yourself.
    The expression boils down to:
    true && true || false && true
    which is:
    true || false && true

    Suppose that we keep left to right evaluation, this means that we get:
    true && true
    which of course evaluates to true

    Suppose we decide to evaluate the logical AND expression first, we get:
    true || false
    which of course evaluates to true

    In fact, I think the C++ standard doesnt actually specify the precedence, but notes that the precedence comes from the syntax. Due to lazy evaluation I think the (x == 2 && b == 2) expression isnt evaluated at all, since the true as the left hand side of the logical OR is sufficient to determine that the entire expression evaluates to true.

    That said, just group your expressions with parentheses if you want to avoid this sort of confusion.
    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

  4. #4
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Which is:
    ((x == 1) && (b == 2)) || ((x == 2) && (b == 2))
    ((1 == 1) && (2 == 2)) || ((1 == 2) && (2 == 2))
    (1 && 1) || (0 && 1)
    1 || 0
    1

    I use parenthesis even if they have precedence, just to be clear, and so it doesn't even matter what the precedence is.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  5. #5
    aoeuhtns
    Join Date
    Jul 2005
    Posts
    581
    Quote Originally Posted by laserlight
    Due to lazy evaluation I think the (x == 2 && b == 2) expression isnt evaluated at all, since the true as the left hand side of the logical OR is sufficient to determine that the entire expression evaluates to true.
    That is what happens, but I think it's better called short-circuiting evaluation than lazy evaluation, which means something similar but somewhat more insane in languages like Haskell.
    There are 10 types of people in this world, those who cringed when reading the beginning of this sentence and those who salivated to how superior they are for understanding something as simple as binary.

  6. #6
    60% Braindead
    Join Date
    Dec 2005
    Posts
    379
    Well, I was wondering because of this statement:

    Code:
    if(x==1 || x==1 &&b==2 &&c==2)
    And I was wondering how the compiler saw that. Is it saying if x equals one or does x equal one and b equals two and c equal two. Or does x equal one or x equals one and b equals two or b equals two and c equals two.

    But I guess the second one would be

    Code:
    if(x==1 || x==1 && b==2 || b==2 && c==2)
    So I'm guessing the double ampersand is taken into consideration before double lines.

    Thanks.
    Code:
    Error W8057 C:\\Life.cpp: Invalid number of arguments in function run(Brain *)

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    In fact, I think the C++ standard doesnt actually specify the precedence
    In my book's precedence tables, && has higher precedence than ||, and I think precedence has to be established to get predictable behavior.

    Due to lazy evaluation I think the (x == 2 && b == 2) expression isnt evaluated at all, since the true as the left hand side of the logical OR is sufficient to determine that the entire expression evaluates to true.
    Easily tested:
    Code:
    int x=1, b=2;
    
    if(x == 1 && b == 2 || (x = 4) && (b = 4))
    {
    	cout<<"x: "<<x<<endl;
    	cout<<"b: "<<b<<endl;
    }
    Set x equal to 2 and run it again.

    Well, I was wondering because of this statement:
    Code:
    if(x==1 || x==1 &&b==2 &&c==2)
    Since && has higher precedence than || as well as left associativity, that conditional is equivalent to:

    x==1 || ( (x==1 &&b==2) &&c==2 )

    So, if x==1 is true, the whole conditional is true, and therefore the compiler doesn't need to evaluate anything on the right side of the ||, i.e. it employs 'lazy evaluation' or 'short circuit' behavior. If x==1 is false, then evaluation has to move to the right of the || to determine whether the whole conditional is true or false. Since x==1 has to be false to move to the right of the ||, and the first thing evaluated on the right is x==1, we know that conditional has to be false. As a result, none of the other conditionals on the right need to be evaluated because all the logical operators are &&'s, and since they are being &&'ed together with something that is false, they have to be false. Therefore, nothing to the right of the first && will ever be evaluated.

    You can prove that to yourself by changing some of the conditionals to assignment statements(remember 0 evaluates to false and anything else evaluates to true), and playing with the initial values of x, b, c and then displaying x, b, and c to see which assignments inside the conditional were executed.
    Last edited by 7stud; 03-07-2006 at 04:37 AM.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    In my book's precedence tables, && has higher precedence than ||, and I think precedence has to be established to get predictable behavior.
    hmm... I decided to look it up, and from section 5 of the C++ Standard:
    "Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified."
    At the end of that is a superscript leading to a note which reads:
    "The precedence of operators is not directly specified, but it can be derived from the syntax."

    Going down to the individual paragraphs, logical AND is given as:
    logical-and-expression:
    inclusive-or-expression
    logical-and-expression && inclusive-or-expression

    while logical OR is given as:
    logical-or-expression:
    logical-and-expression
    logical-or-expression || logical-and-expression

    That a logical-or-expression is defined in terms of a logical-and-expression which is in turn defined in terms of an inclusive-or-expression means that we can conclude that && has a higher precedence than ||

    I suppose that is what the standard means by the precedence being derived from the syntax rather than being listed in some precedence table, which I couldnt find.

    I've always assumed there would be a precedence table though, since every introductory text on the topic I've seen listed it as such - but then it makes sense to simplify the list outright so that it is easier to digest and remember.
    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

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    GCC gives you a warning with this code:
    Code:
    if(x == 1 && y == 1 || z == 1)
    Something like "suggest parenthesis around &&".
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. a Bit of confusion (haha - Pun)
    By Junior89 in forum C++ Programming
    Replies: 1
    Last Post: 06-15-2007, 11:22 PM
  2. Bit processing in C
    By eliomancini in forum C Programming
    Replies: 8
    Last Post: 06-07-2005, 10:54 AM
  3. Porting from 32 bit machine to 64 bit machine!
    By anoopks in forum C Programming
    Replies: 10
    Last Post: 02-25-2005, 08:02 PM
  4. 32 bit v.s. 64 bit
    By xddxogm3 in forum Tech Board
    Replies: 4
    Last Post: 01-14-2005, 09:58 AM
  5. Bit Manipulation Questions
    By CPPNewbie in forum C++ Programming
    Replies: 7
    Last Post: 08-12-2003, 02:17 PM