Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

if statement - short circuit evaluation vs readability

Sometimes, an if statement can be rather complicated or long, so for the sake of readability it is better to extract complicated calls before the if.

e.g. this:

if (SomeComplicatedFunctionCall() || OtherComplicatedFunctionCall()) {     // do stuff } 

into this

bool b1 = SomeComplicatedFunctionCall(); bool b2 = OtherComplicatedFunctionCall();  if (b1 || b2) {     //do stuff } 

(provided example is not that bad, it's just for illustration... imagine other calls with multiple arguments, etc.)

But with this extraction I lost the short circuit evaluation (SCE).

  1. Do I really lose SCE every time? Is there some scenario where the compiler is allowed to "optimize it" and still provide SCE?
  2. Are there ways of keeping the improved readability of the second snippet without losing SCE?
like image 641
relaxxx Avatar asked Oct 17 '16 08:10

relaxxx


People also ask

What are the advantages about short-circuit evaluation?

The advantages of C#'s short-circuit evaluation. There are two benefits to the short-circuit behaviour of the && and || operators. It makes our true/false conditions more efficient since not every expression has to be evaluated. And short-circuiting can even prevent errors because it skips part of the code.

Is IF statement short-circuit?

Evaluation short-circuiting is a feature of the logical operators AND and OR . It is meant to speed up code execution, but sometimes it's misused to simulate if statements.

Does C have short-circuit evaluation?

In imperative language terms (notably C and C++), where side effects are important, short-circuit operators introduce a sequence point – they completely evaluate the first argument, including any side effects, before (optionally) processing the second argument.

Does JavaScript short-circuit if statement?

Yes, JavaScript has "short-circuit" evaluation. if (true == true || foo.


2 Answers

One natural solution would look like this:

bool b1 = SomeCondition(); bool b2 = b1 || SomeOtherCondition(); bool b3 = b2 || SomeThirdCondition(); // any other condition bool bn = bn_1 || SomeFinalCondition();  if (bn) {   // do stuff } 

This has the benefits of being easy to understand, being applicable to all cases and having short circuit behaviour.


This was my initial solution: A good pattern in method calls and for-loop bodies is the following:

if (!SomeComplicatedFunctionCall())    return; // or continue  if (!SomeOtherComplicatedFunctionCall())    return; // or continue  // do stuff 

One gets the same nice performance benefits of shortcircuit evaluation, but the code looks more readable.

like image 94
Horia Coman Avatar answered Sep 29 '22 15:09

Horia Coman


I tend to break down conditions onto multiple lines, i.e.:

if( SomeComplicatedFunctionCall()  || OtherComplicatedFunctionCall()   ) { 

Even when dealing with multiple operators (&&) you just need to advance indention with each pair of brackets. SCE still kicks in - no need to use variables. Writing code this way made it much more readible to me for years already. More complex example:

if( one()  ||( two()> 1337   &&( three()== 'foo'    || four()     )    )  || five()!= 3.1415   ) { 
like image 37
AmigoJack Avatar answered Sep 29 '22 15:09

AmigoJack