if a is true, would the compiler evaluate the value of b (and c)? |
No.
As you said, if a is true then the compiler (or rather, the compiiled object code) won't bother to evaluate anything to the right of it.
But these is a gotcha -- this is only the case when you use the built-in operator|| and operator&&. If you override them, then the behaviour changes. See following post for further info.
(Due to the change in behaviour, it is strong recommended you do not overload these operators. Or operator, -- the comma (or seqence) operator.)
To see what's up, you can implement a Boolean class which provided a bool cast overator, but not it's own comparison methods. (see below.)
does the compiler know in advance that there's only logical ORs |
You can mix ||s and &&s and short-circuit evaluation still applies. Though not usually as efficently.
Andy
PS See 20 -- "Avoid Overloadinf &&, || or , (comma)" in
C++ Coding Standards by Sutter and Alexandrescu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
#define DEBUG
#include <iostream>
#include <iomanip>
using namespace std;
class Boolean {
private:
char m_name;
bool m_val;
public:
Boolean(char name) : m_name(name), m_val(false) {
}
Boolean(char name, bool val) : m_name(name), m_val(val) {
}
Boolean(const Boolean& that) : m_name(that.m_name), m_val(that.m_val) {
}
Boolean& operator=(const Boolean& that) {
m_name = that.m_name;
m_val = that.m_val;
return *this;
}
operator bool() const {
#ifdef DEBUG
cout << "operator bool() for " << m_name << " returns " << m_val << endl;
#endif
return m_val;
}
};
int main(){
cout << boolalpha;
Boolean a('a', true);
Boolean b('b', true);
Boolean c('c', true);
std::cout << "a || b || c" << endl;
if ( a || b || c ) {
std::cout << "as least one of a, b, c is true" << endl;
} else {
std::cout << "a, b, c are all false" << endl;
}
std::cout << endl;
std::cout << "a && b && c" << endl;
if ( a && b && c ) {
std::cout << "all a, b, c are true" << endl;
} else {
std::cout << "as least one of a, b, c is false" << endl;
}
std::cout << endl;
return 0;
}
|
Results (for built-in operator|| and operator&&):
a || b || c
operator bool() for a returns true
as least one of a, b, c is true
a && b && c
operator bool() for a returns true
operator bool() for b returns true
operator bool() for c returns true
all a, b, c are true |
As you can see, in the first, || case only a is asked what it's value is. Whereas in the latter, && case, all Boolean variables are asked to give their value.