Thread: shortcutting in boolean expressions?

  1. #1
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229

    shortcutting in boolean expressions?

    Eg, if I write something like this
    Code:
    if (a() && b()) {
         //.....
    }
    is it possible that b() doesn't get evaluated if a() returns false? What does the standard say about this?

    Thank you

  2. #2
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Yes, that's right. If a() returns false, everything to the right of the && won't be executed.

  3. #3
    coder
    Join Date
    Feb 2008
    Posts
    127
    The answer is: b() won't get evaluated if a() returns false.
    I don't know what the standard say about, but this program will tell you:
    Code:
    #include <iostream>
    using namespace std;
    
    bool a ()
    {
    	cout << "a\n";
    	return 0;
    }
    
    bool b ()
    {
    	cout << "b\n";
    	return 1;
    }
    
    int main ()
    {
    	if (a() && b());
    	return 0;
    }

  4. #4
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    hmm I see. Thanks for the help. I was just making sure that it is the standard behaviour.

    btw, then, what should I write if I want all of them to be evaluated regardless of the return values? (except making a bunch of temporary variables and recording each return values first of course)

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The standard says that b() will definitely not be evaluated if a() is false. Code which actually uses this behavior is not uncommon. For instance:

    Code:
    A() && B() && C() && D();
    Will invoke the functions A, B, C, D, in that order, as long as they return true. You can use this to do a multi-part operation in sequence, stopping if anything fails. The alternative using if-statements would be:

    Code:
    if(A())
    {
        if(B())
        {
            if(C())
            {
                D();
            }
        }
    }
    The || operator can be used in the same way but the opposite sense.

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by cyberfish View Post
    hmm I see. Thanks for the help. I was just making sure that it is the standard behaviour.

    btw, then, what should I write if I want all of them to be evaluated regardless of the return values? (except making a bunch of temporary variables and recording each return values first of course)
    Using temp vars - is a way, You cannot force compiler evaluate all members of logical expression.

    If your function return only 0 and 1 - you can however switch to binary &
    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

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cyberfish View Post
    btw, then, what should I write if I want all of them to be evaluated regardless of the return values? (except making a bunch of temporary variables and recording each return values first of course)
    Somewhat obscure:

    Code:
    !!a() & !!b()
    Although this does not guarantee the order of evaluation for a() and b(). It does make sure they both get called, and the value of the expression is the same as for the && operator.

  8. #8
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    hmm I see... Thanks for the suggestions.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Note that this is GUARANTEED by the standard, and it allows things like this to work:
    Code:
    if (fgets(buffer, sizeof buffer, stdin) != NULL && buffer[0] != '\n') ... 
    
    // or
    if (x && y / x > 7) ...   // if x == 0, we can't divide by x. 
    
    // or
    if (ptr != NULL && ptr->member == mymember) ...
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by cyberfish View Post
    btw, then, what should I write if I want all of them to be evaluated regardless of the return values? (except making a bunch of temporary variables and recording each return values first of course)
    Why would you want to?
    If you only want your if statement to execute if both functions return true, why waste time executing b() if a() already returned false?

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cpjust View Post
    Why would you want to?
    If you only want your if statement to execute if both functions return true, why waste time executing b() if a() already returned false?
    Because the function call is part of what is happening. Maybe you want both a() and b() to run but you are also interested if one of them failed. I'd personally just serialize it and check:

    Code:
    a_status = a();
    b_status = b();
    if(a_status && b_status)
        ...

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Of course, if you have a loop header, this might not work. You could use the comma operator instead.
    Code:
    while(a_status = a(), b_status = b(), a_status && b_status)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by CornedBee View Post
    Of course, if you have a loop header, this might not work. You could use the comma operator instead.
    Code:
    while(a_status = a(), b_status = b(), a_status && b_status)
    But couldn't those be evaluated in any order, or is that only for function parameters?

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    But couldn't those be evaluated in any order, or is that only for function parameters?
    There is a sequence point at the comma operator, so the order of evaluation is defined here.
    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

  15. #15
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Why would you want to?
    If you only want your if statement to execute if both functions return true, why waste time executing b() if a() already returned false?
    because a() and b() have side effects.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Novice needs help
    By ghaasemi in forum C++ Programming
    Replies: 9
    Last Post: 05-30-2009, 08:20 AM
  2. Regular expressions [Boost]
    By Desolation in forum C++ Programming
    Replies: 8
    Last Post: 12-30-2006, 10:10 PM
  3. Liitle help with boolean expressions
    By Voyd in forum C++ Programming
    Replies: 2
    Last Post: 05-30-2006, 08:17 PM
  4. Casting boolean as string
    By doofusboy in forum C Programming
    Replies: 11
    Last Post: 11-10-2005, 12:24 PM
  5. Use struct to create a boolean type
    By skyglin in forum C Programming
    Replies: 6
    Last Post: 06-18-2003, 08:21 PM