6

I've seen some code that looks like this:

if (a) return false;
if (b) return false;
if (c) return false;
return true;

Is there any difference in performance between the above and

if (a || b || c) return false;
else return true;

In general, what would be the preferred case to handle this? Maybe without the else in my second example?

EDIT: It seems a lot of people were mislead by the fact that I return true or false and suggest returning !(a || b || c). This wasn't what I wanted to ask. Imagine if instead of returning true or false I want to return "Yes" or "No", or 23423 or 3.

user818794
  • 73
  • 4
  • 3
    why not simply `return a || b || c` (assuming, that the actual expressions `a`, `b`, and `c` are reasonably short...) – Dirk Jun 28 '11 at 08:50
  • 1
    He might want to return 1 and 2 rather than true or false? – RAY Jun 28 '11 at 08:52
  • 2
    @Dirk: it's be `return !(a || b || c)` for the examples given, but I wholeheartedly agree with using `return` *expression*. – Tony Delroy Jun 28 '11 at 09:00
  • 1
    "Imagine if instead of returning true or false"... `return !(a || b || c) ? "Yes" : "No";` (or `return "Yes\0No\0" + (a || b || c) * 4;` ;-P) – Tony Delroy Jun 28 '11 at 09:56
  • WTF! `return "Yes\0No\0" + (a || b || c)*4;`?? Please, don't suggest things you would not like your coworkers to write, you might get someone into thinking that obfuscating code is a good idea. Surely you don't want to maintain a product filled with that type of code... – David Rodríguez - dribeas Jun 28 '11 at 11:31
  • @David: I guess even clearly-labelled jokes come under the new "not constructive" category? After all, we wouldn't want people using SO because they enjoy it ;-P – Steve Jessop Jun 28 '11 at 11:56
  • @Tony +1 for readability - I knew when I edited my comment that someone would suggest doing this :) – user818794 Jun 28 '11 at 13:45
  • @Steve Jessop: Don't you understand! SO cannot be made enjoyable, it is too addictive as it is to make it better! – David Rodríguez - dribeas Jun 28 '11 at 15:58
  • @David: hey... if you make me laugh at my desk my colleagues might have me sent to the funny farm...! – Tony Delroy Jun 29 '11 at 01:03

5 Answers5

5

The only advantage to either one would be readability, it would be reasonable for an optimizing compiler to generate nearly identical code for the two cases.

If the 3 tests are short then return !(a||b||c); is perfectly reasonable

If however they are long function calls then your first example would be easier to read.

tobyodavies
  • 27,347
  • 5
  • 42
  • 57
4

It all comes down to how the compiler compiles the code. For all practical purposes, they are identical. (As long as you make sure to use short-curcuited OR "||")

RAY
  • 6,810
  • 6
  • 40
  • 67
  • 1
    @RAY: tell me how to _not_ use shortcut OR "||" in C++? – sehe Jun 28 '11 at 08:54
  • I'm a little rusty on C++ now, but I believe if a and b and c are numbers, you can use the bitwise or because C++ considers 0 to be false, and non-zero to be true. Please feel welcomed to correct me though. – RAY Jun 28 '11 at 08:57
  • @RAY: you're confusing bitwise with logical, which in C++ are separate operators (namely: `|` vs. `||`). – sehe Jun 28 '11 at 08:58
  • 1
    If I remember correctly, C++ doesn't segregate bool and numericals that clearly... – RAY Jun 28 '11 at 08:59
  • @Ray: you're correct... that would work in most cases, though it could be less efficient (for having to evaluate all of a, b and c) or more (for avoiding branching statements). It's definitely a bad idea though, as it suggests some subtler significance to the bit values that doesn't exist. And, it doesn't work so well for AND, e.g. `1 & 2` is `false` while `1 && 2` is `true`. – Tony Delroy Jun 28 '11 at 09:04
  • @sehe: well, C++ isn't all short circuit you know - see my answer: http://stackoverflow.com/questions/1758608/is-there-an-non-short-circuited-logical-and-in-c/5577866#5577866 – Tony Delroy Jun 28 '11 at 09:06
  • @Tony: That could be relevant depending on the type of `a`, `b`, `c` (and the presence of overloaded operators in the accessible namespace scopes) – sehe Jun 28 '11 at 09:08
  • @sehe: the way to not use short-circuit `operator||` is to overload it. The type of expressions `a`, `b`, `c` isn't stated here, and if it's not a built-in type then `operator||` does *not* short-circuit - they will all be evaluated. – Steve Jessop Jun 28 '11 at 09:39
  • @Steve Jessop: my statement (`[...] and the presence of overloaded operators in the accessible namespace scopes`) is more accurate. The thing is, even non-builtin types will shortcut with proper implicit conversion to bool (e.g.); Now ADL/Koenig Lookup is tricky enough to make that less than obvious overloads of the logical operators exist. – sehe Jun 28 '11 at 11:02
1

In short: there are no significant differences in the code, and you could further shorten your code by writing it as return !(a || b || c);


If your conditions are really simple, for example if (fata_is_invalid || login_failed) then you could combine them all into one line like you suggested.

Sometimes you will see conditions that are simply massive, and in that case it's preferable to split them up into smaller chunks (either through multiple if-statements or by re-formatting your code). Either way, it is just a readability thing - use whatever method you prefer (or whatever is advocated by your "style guide").

The compiler is super-sweet and will produce (almost) identical code for whatever you write in those cases.

evgeny
  • 2,564
  • 17
  • 27
0

&&, || and ? are short-circuit operators in C++, which means that the second argument is evaluated only if the first is not determining the value of the expression.

That means you could simply write, for your sample code:

return !(a || b || c);
Marius Bancila
  • 16,053
  • 9
  • 49
  • 91
  • 1
    "&&, || and ? are short-circuit operators in C++" - unless they're overloaded. If there's any chance that the original code is relying on the fact that `b` isn't evaluated if `a` is true, then you need to check the types involved before making this change. – Steve Jessop Jun 28 '11 at 09:41
0

Separate ifs and using || operator are not neccessarily identical! If any of a, b or c are user defined types and overload either || or conversion operator to any integer or pointer type then the two constructs may yield different results!

Tomek
  • 4,554
  • 1
  • 19
  • 19