Best way to format if statement with multiple conditions - if-statement

If you want to some code to execute based on two or more conditions which is the best way to format that if statement ?
first example:-
if(ConditionOne && ConditionTwo && ConditionThree)
{
Code to execute
}
Second example:-
if(ConditionOne)
{
if(ConditionTwo )
{
if(ConditionThree)
{
Code to execute
}
}
}
which is easiest to understand and read bearing in mind that each condition may be a long function name or something.

I prefer Option A
bool a, b, c;
if( a && b && c )
{
//This is neat & readable
}
If you do have particularly long variables/method conditions you can just line break them
if( VeryLongConditionMethod(a) &&
VeryLongConditionMethod(b) &&
VeryLongConditionMethod(c))
{
//This is still readable
}
If they're even more complicated, then I'd consider doing the condition methods separately outside the if statement
bool aa = FirstVeryLongConditionMethod(a) && SecondVeryLongConditionMethod(a);
bool bb = FirstVeryLongConditionMethod(b) && SecondVeryLongConditionMethod(b);
bool cc = FirstVeryLongConditionMethod(c) && SecondVeryLongConditionMethod(c);
if( aa && bb && cc)
{
//This is again neat & readable
//although you probably need to sanity check your method names ;)
}
IMHO The only reason for option 'B' would be if you have separate else functions to run for each condition.
e.g.
if( a )
{
if( b )
{
}
else
{
//Do Something Else B
}
}
else
{
//Do Something Else A
}

Other answers explain why the first option is normally the best. But if you have multiple conditions, consider creating a separate function (or property) doing the condition checks in option 1. This makes the code much easier to read, at least when you use good method names.
if(MyChecksAreOk()) { Code to execute }
...
private bool MyChecksAreOk()
{
return ConditionOne && ConditionTwo && ConditionThree;
}
It the conditions only rely on local scope variables, you could make the new function static and pass in everything you need. If there is a mix, pass in the local stuff.

if ( ( single conditional expression A )
&& ( single conditional expression B )
&& ( single conditional expression C )
)
{
opAllABC();
}
else
{
opNoneABC();
}
Formatting a multiple conditional expressions in an if-else statement this way:
allows for enhanced readability:
a. all binary logical operations {&&, ||} in the expression shown first
b. both conditional operands of each binary operation are obvious because they align vertically
c. nested logical expressions operations are made obvious using indentation, just like nesting statements inside clause
requires explicit parenthesis (not rely on operator precedence rules)
a. this avoids a common static analysis errors
allows for easier debugging
a. disable individual single conditional tests with just a //
b. set a break point just before or after any individual test
c. e.g. ...
// disable any single conditional test with just a pre-pended '//'
// set a break point before any individual test
// syntax '(1 &&' and '(0 ||' usually never creates any real code
if ( 1
&& ( single conditional expression A )
&& ( single conditional expression B )
&& ( 0
|| ( single conditional expression C )
|| ( single conditional expression D )
)
)
{
... ;
}
else
{
... ;
}

The first example is more "easy to read".
Actually, in my opinion you should only use the second one whenever you have to add some "else logic", but for a simple Conditional, use the first flavor. If you are worried about the long of the condition you always can use the next syntax:
if(ConditionOneThatIsTooLongAndProbablyWillUseAlmostOneLine
&& ConditionTwoThatIsLongAsWell
&& ConditionThreeThatAlsoIsLong) {
//Code to execute
}
Good Luck!

The question was asked and has, so far, been answered as though the decision should be made purely on "syntactic" grounds.
I would say that the right answer of how you lay-out a number of conditions within an if, ought to depend on "semantics" too. So conditions should be broken up and grouped according to what things go together "conceptually".
If two tests are really two sides of the same coin eg. if (x>0) && (x<=100) then put them together on the same line. If another condition is conceptually far more distant eg. user.hasPermission(Admin()) then put it on it's own line
Eg.
if user.hasPermission(Admin()) {
if (x >= 0) && (x < 100) {
// do something
}
}

The second one is a classic example of the Arrow Anti-pattern So I'd avoid it...
If your conditions are too long extract them into methods/properties.

The first one is easier, because, if you read it left to right you get:
"If something AND somethingelse AND somethingelse THEN" , which is an easy to understand sentence. The second example reads "If something THEN if somethingelse THEN if something else THEN", which is clumsy.
Also, consider if you wanted to use some ORs in your clause - how would you do that in the second style?

In Perl you could do this:
{
( VeryLongCondition_1 ) or last;
( VeryLongCondition_2 ) or last;
( VeryLongCondition_3 ) or last;
( VeryLongCondition_4 ) or last;
( VeryLongCondition_5 ) or last;
( VeryLongCondition_6 ) or last;
# Guarded code goes here
}
If any of the conditions fail it will just continue on, after the block. If you are defining any variables that you want to keep around after the block, you will need to define them before the block.

I've been facing this dilemma for a long time and I still can't find a proper solution. In my opinion only good way is to first try to get rid of conditions before so you're not suddenly comparing 5 of them.
If there's no alternative then like others have suggested - break it down into separete ones and shorten the names or group them and e.g. if all must be true then use something like "if no false in array of x then run".
If all fails #Eoin Campbell gave pretty good ideas.

When condition is really complex I use the following style (PHP real life example):
if( $format_bool &&
(
( isset( $column_info['native_type'] )
&& stripos( $column_info['native_type'], 'bool' ) !== false
)
|| ( isset( $column_info['driver:decl_type'] )
&& stripos( $column_info['driver:decl_type'], 'bool' ) !== false
)
|| ( isset( $column_info['pdo_type'] )
&& $column_info['pdo_type'] == PDO::PARAM_BOOL
)
)
)
I believe it's more nice and readable than nesting multiple levels of if(). And in some cases like this you simply can't break complex condition into pieces because otherwise you would have to repeat the same statements in if() {...} block many times.
I also believe that adding some "air" into code is always a good idea. It improves readability greatly.

Related

Checking if a given group of integers contains a 0 value

Suppose I have a bunch of integers (10~20) and need to check if any of them equals 0. What's the most efficient way to do it? I don't want to evaluate a giant if(a=0 || b=0 || c=0 ||...) statement. I thought of if(abc... = 0) but if I remember correctly multiplication isn't a very quick process. Are there any other tricks, such as bit wise operations that would work? I'm trying to think as low level as possible to make this super efficient.
I'm pretty sure the fastest and clearest way to do this is with an explicit test:
int has_zero = !a || !b || !c || !d || !e ...;
Because the || and && are short-circuiting operators in C, evaluation stops as soon as the final result is known, so if (for instance) the b variable is zero, that satisfies the expression as true and stops evaluating the rest.
#AbhayAravinda suggested that !(a && b && c && d ...) might be more efficient, but I don't think so; because this is not so much doing an explicit not operation, but a low-level test-against-zero, this is a really easy test for pretty much any architecture to do reliably. I did a quick look at optimized assembler for both versions and there was no clear winner for performance, but I think the first version is clearer.
If every single cycle matters, then check both versions on your platform, but on my 64-bit Intel system, both gcc and clang do in fact generate the same assembly for both versions (with optimizations turned on).
Simple test code:
int a, b, c, d, e, f;
int test_or()
{
return !a || !b || !c || !d || !e || !f;
}
int test_and()
{
return ! (a && b && c && d && e && f);
}
int main()
{
return test_or() | test_and();
}
Compile this with gcc -S -O testfile.c and look at the resulting .s file.
Test each one in turn. Exploit the short-circuiting property of ||; place the variables in descending order of the probability of each being zero:
if (!a/*most likely to be zero*/ || !b || ...){
// one of them is zero
}
Most people give an answer like:
!a || !b || ...
(where a is the most probable one of being zero)
The idea is that, in case a is zero, then the rest of the sequence is not evaluated (because of not being necessary), which is a kind of optimisation, performed by the compiler.
This turns the question into: does your compiler perform this optimisation or not (and in case of "possibly yes", what are the parameters in order to enforce this)?
Can you tell us which compiler (version) you're working with? This might enable us verifying this.
You may look at the assembler output.
The !a || !b || !c || !d || !e || !f will give you a bunch of cmp and je statements. One pair for each variable. Because of boolean short cut evaluation, it may run very fast. Or not.
The maybe better and deterministic solution is using the bitwise AND operator. If one operand is 0, then the result will be 0. So someting like:
if (a & b & c & d & e & f & g & h & i & j & k)
will result in one mov and then and statements for each variable.
So, if the variable that is 0 is in the 2nd half of the if statement, then the bitweise AND will be faster.

Shorten If Statement And Making It Less Redundant

New here. I was just wondering if it's possible to make this if statement shorter and less redundant.
if (!a && b)
{
if (c == d && e > 0)
{
return;
}
}
else if (a && !b)
{
if (c != d)
{
return;
}
}
else if (!a && !b)
{
return;
}
Here's what I've ended up with
if ((!a && b && c == d && e > 0) || (a && !b && c != d) || (!a && !b))
{
return;
}
All I did was join nested if statements with an && operator, and if-else if statements with || operator. Now I'm stuck, is it possible to make this even shorter? If you could share some tips or your way of approaching this kind of scenario, I'd be glad to hear it out.
Neither of the approaches is readable. It will be better to create a function that indicates the kinds of checks you are performing.
if ( !my_very_sensible_special_conditions_are_met(a, b, c, d, e) )
{
return;
}
After that, whether you use the first approach or the second approach in the implementation of the function is less of an issue.
condition ladder(if,else if) shortening
As you mentioned, in all blocks(if, else if) if you are just having the same set of statements then you can put all the conditions with a single if statement with proper conditions with appropriate brackets.By doing this lines of code will get reduced But you will have some disadvantages as per my point of view
Readability will get reduced
In future, if you want to change your code for a particular condition, it will take some time to change.it is not that much easy as you do in condition ladder
if you are not having any problem with the above two points, you can go with your approach itself.But code your conditions as atomic as possible.it will help you out in a long run.
Given the number and complexity of conditions, I'd at least consider making it table driven. For the moment, I've assumed that a and b are actually ints containing either a 0 or a 1.
int index = a | (b<<1) | (int(c==d)<<2) | (int(e>0) << 3);
static const bool should_return[] = {
1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0
};
if (should_return[index])
return;
The table is still basically incomprehensible, but at least it encodes that incomprehensibility fairly compactly, and makes it easy for the code to use it.
Since you commented that you are always returning, and since your code does not specify if you do anything else in these if - else cases why not do just
if (! (a && b) )
{
return;
}
You can shorten it a tiny bit further:
if (!a && !b || !b && c != d || !a && c==d && e> 0) {
return;
}
But that doesn't increase readability and most likely also not performance. What I would focus on is, what reads most natural with the real variable names.
As a general advice, I'd start with checking the simpler / shorter conditions first. That makes it often more easier to see if you make redundant checks in the following ones.
In any case, as #R.Sahu suggested, a complex condition like that belongs into a separate, named and commented function. If you don't find a good name for it use something generic like e.g. check_<main_function>_preconditions.
EDIT:
Sorry, I can't resist: If you wan to go overboard, you can make it pretty compact by throwing in a trinary statement:
if (!a && !b || c != d ? !b : !a && e> 0) {
return;
}
DON'T do that in production code!

Understanding "Bitwise-And (&)" and "Unary complement(~)" in c++

I have some trouble understanding Bitwise-And and Unary Complement when both are used in this code snippet
if((oldByte==m_DLE) & (newByte==m_STX)) {
int data_index=0;
//This below line --- does it returns true if both the oldByte and newByte are not true
//and within timeout
while((timeout.read_s()<m_timeout) & ~((oldByte==m_DLE) & (newByte==m_ETX))) {
if(Serial.available()>0) {
oldByte=newByte;
newByte=Serial.read();
if(newByte==m_DLE) {
.
.
.
are the both operators & ~are performing a logical not operation like checking until if both oldByte and newByte are false
The above code is from the link --> line 227 of the code
I am trying to use the implement the code for my application in C but without the timing functions
if((oldByte==DLE) && (newByte== STX)) {
data_index = 0;
// is this the correct implematation for above C++ code to C
while(! ((oldByte== DLE) && (newByte== ETX))){
oldByte = newByte;
Is this method correct for implementing in C
(timeout.read_s()<m_timeout) & ~((oldByte==m_DLE) & (newByte==m_ETX))
is equivalent to (but probably less readable than)
(timeout.read_s()<m_timeout) && !(oldByte==m_DLE && newByte==m_ETX)
which is equivalent to (and IMO less readable than)
(timeout.read_s()<m_timeout) && (oldByte!=m_DLE || newByte!=m_ETX)
Edit: should add a caveat about short-circuiting. Although the particular example statements will all return the same value, using && or || will skip evaluating pieces that can't impact the result. This isn't important in your specific example, but could be very important in an example like this:
(oldByte!=nullptr & *oldByte == m_ETX) // will crash when oldByte=nullptr.
(oldByte!=nullptr && *oldByte == m_ETX) // will evaluate to false when oldByte=nullptr.
Since the equality-operator (==) yields 0 or 1 as a result, you can use bitwise and, too. (foo==1) & ~(bar==1) works too, since the AND with (foo==1), which always results in 1 and 0, masks all other bits in ~(bar==1). However, it is strongly recommended to use the logical counterparts &&, || and !.
The following would not work as expected:
if (~(bar == 1) & ~(foo == 1))
e.g. if foo = bar = 1, then it would evaluate to 0xfffffffe on ia32, which is different from 0 and therefore "TRUE"

Logical confusion for giving if condition

I want to give a condition in such a way that if all values are either 0 or 1, then some logic is executed.
I have three variables.
0 0 0 -> evaluates to True
1 1 1 -> evaluates to True
All other combinations evaluate to False. How can I write the logic for this?
bool condition1, condition2, condition3;
...
if ((condition1 == condition2) && (condition2 == condition3))
or
bool allThreeEqual = (condition1 == condition2) && (condition2 == condition3);
Start by expressing what you're thinking in words as simple code:
int a, b, c;
// ...
bool eval = false; // assume false, prove otherwise
if( (a==0) && (b==0) && (c==0) )
eval = true;
else if( (a==1) && (b==1) && (c==1) )
eval = true;
Some would argue that the above is not elegant. I disagree. The above is simple, straightforward, and dumb-simple to understand, maintain and extend. Sounds like the definition of elegant to me.
Once this simple logic has been written, you can evaluate if you need to do performance benchmarking on this code. If you do, and you determine that this is indeed a real bottleneck, then you can mode forward optimizing it, perhaps by leveraging the transitive relationship between the elements. Almost every time however this will be plenty fast enough, and there will be no need to make any changes at all.

c++ what is the correct syntax here?

what is the correct syntax for checking a varable value and then setting a varable in the same condition also checking that new set varables var, all in one if statement?
so basically something like
if(this->somevar > 0 && this->newvar = this->GetNewVar(this->somevar),this->newvar > 0)
i know that is not the correct syntax or at least its not working for me anyway, hence the topic, i am using that as an example, so if this->somevar is null or 0, i don't want it to execute the next condition which is && this->newvar = this->GetNewVar(this->somevar,this->newvar but instead skip the statement and ignore that part.
what is the correct syntax for something like this?
&& is an operator with short circuit evaluation, right part is not executed if left part is true.
But why don't you simply write:
if(this->somevar > 0)
{
this->newvar = this->GetNewVar(this->somevar);
if (this->newvar > 0)
{
...
This will certainly makes things clearer ...
the logical AND && operator is short-circuited if this->somevar evaluates to zero, meaning the rest of your if expression would not be evaluated in that situation
The expression after the comma is not necessary. Also, there is one thing missing, parentheses arround the assignment:
if(this->somevar > 0 && (this->newvar = this->GetNewVar(this->somevar)) > 0)
Without the parentheses you may end up setting this->newvar to the value of the boolean expression
this->GetNewVar(this->somevar),this->newvar > 0, which will be evaluated to a boolean result (true/false which, in turn, may be converted to 0 or 1 or -1 depending on the compiler, when cast to the type of this->newvar).
I think only the bit after the comma is evaluated for the if condition. The expression on the left of the comma is ignored.
int main() {
if( false, true) { cout << " got to if( false, true ) "; }
if ( true, false ) { cout << "got to if( true, false ) "; }
}
to answer your question, you can put anything on the left of the comma and do whatever you like, as long as the expression you want to evaluate is the last expression in the list.
so if ( exp1, exp2, exp3 , exp4 ) dowhatever(); only gets run if exp4 is true. You should really run exp1 to exp3 outside the if condition for readability.