I see many examples using the unlikely macro (not the C++20 attribute) as if( unlikely( server == 0 ) ), but never combining them both as if( unlikely( server == 0 ) || unlikely( client == 0 ) ) or if( unlikely( server == 0 || client == 0 ) ).
Can I need to use two unlikely on two conditionals for the same if or the unlikely is interpreted correctly if used only once in the whole if condition as in if( unlikely( server == 0 || client == 0 ) )?
Other questions about unlikely:
gcc likely unlikely macro usage
efficient, extremely-unlikely conditionals?
likely and unlikely macros
likely/unlikely instead of if/else
Related
In my if statement, the first condition for && is 0 (false), so the expression 0 && (a++) is equal to 0, right? Then 0==0 it should be true. Why am I getting else here? Please explain!
int a=0;
if(0 && (a++)==0)
{
printf("Inside if");
}
else
{
printf("Else");
}
printf("%i",a);
The == operator has a higher priority than the && operator, so this line:
if(0 && (a++)==0)
is treated like this:
if( 0 && ((a++)==0) )
So the whole expression under the if is false, and a++ is not even evaluated due to short circuitry of the && operator.
You can read about Operator Precedence and Associativity on cppreference.com.
When in doubt, you should use parenthesis to express your intention clearly. In this case, it should be:
if( (0 && (a++)) == 0 )
Though, it does not make any sense, as it always evaluates to true and a++ is not incremented here, either.
As already mentioned, the precedence of == is higher than precedence of &&, so the statement is resolved into
if( 0 && ((a++)==0))
However, still even if you add the correct order of brackets, a++ returns the original value of a, which is 0, but the a is incremented. If you want to return the updated value of a, you should write ++a
if( ((++a) && 0) == 0 )
Although the question seems easy it's very error-prone.
We need to know the precedence of various operators involved in this.
1. postfix (++)
2. ==
3. Logical AND (&&)
the final expression can be seen as: if ( (0 && (a++)) == 0 )
which is true. Hence statement under if is evaluated to be true.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
In code I come to situation like this:
if (a && b || c && d || e && f || g && h){
// do something
}
Like this:
if len(env.workers) == 0 && env.minQueue.Len() == 0 || len(env.workers) == len(env.daemonList) && env.minQueue.Len() == 0 || len(env.workers) > 0 && len(env.workers) == len(env.daemonList) {
env.shouldStop = true
return nil
}
But it's hard to debug and find errors. Is there any way to use more friendly constructuion to replace such statement.
As #Eugene mentioned it's always good idea to break long expressions like this into multiple smaller expressions.
exp1 = a && b
exp2 = c && d
exp3 = exp1 || exp2
exp4 = e && f
exp5 = g && h
exp6 = exp4 || exp5
exp7 = exp3 || exp6
if(exp7){
//doSomething
}
This may look absurd in beginning but believe me it has long way to go, at any point you can come back to the above code and easily understand what's cooking there. In fact if you like using debuggers then doing this would make your life way easier.
Also in point of performance, all you are doing is making extra 7 boolean variables. It's insignificant when code readability is concerned. And the thumb rule for better code readability is naming your variable right, not exp1,2,....
You use len(env.daemonList), len(env.workers) and env.minQueue.Len() multiple times. Storing them in variables not only shortens up that long condition, but also gives you variables that can be referenced when debugging.
You could write it as:
w_len = len(env.workers)
d_len = len(env.daemonList)
q_len = env.minQueue.Len()
if w_len == 0 && q_len == 0 || w_len == d_len && q_len == 0 || w_len > 0 && w_len == d_len {...
Now, of course the problem here is that while shorter, the names aren't as descriptive. You could give them better names at the cost of verbosity. How much you want to lean in each direction is a matter of taste and context.
This also doesn't "get rid" of the if like the title states, but that's not always a great goal to have. ifs aren't necessarily bad.
1.Imagine condition if (obj.is_x() || obj.is_y() || obj.is_z())
Will obj.is_y() and obj.is_z() be called and evaluated if obj.is_x() returned true ?
2.Is this a bad idea(in general)? Does this code look bad ?
bool isbn13_prefix_valid (const string& prefix)
{
unsigned num = stoi(prefix);
if (num == 978 || num == 979) return 1; //super common ones
else if ( num >= 0 && num <= 5 || num == 7 || num >= 600 && num <= 649
|| num >= 80 && num <= 94 || num >= 950 && num <= 989
|| num >= 9900 && num <= 9989 || num >= 99900 && num <= 99999)
return 1;
return 0;
}
No, it will not, due to short-circuiting.
Yes, that code looks bad. Not because it's incorrect, but because you're stuffing an extremely long conditional into a single if statement. Try refactoring your code to make it cleaner.
Your code is absolutely fine. I'd like to see a comment where these strange numbers come from, that's all.
Turning it into a dozen trivial functions as has been suggested is in no way helpful. It actually makes it a lot harder to read the code, because it gets spread out over many many lines of code. Yes, it is complex. But that's due to the problem being complex, and trying to spread the complexity out doesn't help one bit.
Your actual question: In a || b, a is evaluated first. If it is true, then b is not evaluated and the result is true. If a is false, then b is also evaluated and the result is true or false, depending on the result of b.
An optimising compiler may start evaluating b before it has finished evaluating a, if it can prove that the evaluation of b has no side effects, and if it believes that (mostly due to parallelism in the hardware) it is on average faster to evaluate as much in parallel as possible, even if some things are evaluated when it wasn't necessary. But this is not noticable in the results of your code, and will only make the code faster.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm writing a function that is passed a character as the first argument and an integer as the second. I need to validate both simultaneously. Specifically, the character must be between A and J (including A and J), and the integer must be between 1 and 10 (including 1 and 10).
The line I wrote is:
if (toupper(row) < 'A' || toupper(row) > 'J' || col < 1 || col > 10)
{
return 0;
}
else
{ ... rest of function ... }
but this is not working correctly. In my book I read that you could perform comparisons with characters because they really are just integers themselves, but I can't figure out why ths won't work. Could anyone point me in the right direction?
Edit to address some comments
0 is the number we're supposed to return if the input is not valid.
This line of code is part of a project that is being graded by a "test driver" that my teacher wrote. The test driver is reporting that my function is not returning the correct result when the input is invalid (character that is not between A or J, or a number that is lower than 1 or greater than 10).
I structured my code so that if the statement above is true, then it returns the code we were supposed to return, otherwise it proceeds with the rest of the function... So I can't figure out why his test driver is telling me that I'm not returning the code when given invalid input. The other problem is he doesn't let us see what the test driver is sending to our function, so I have no way of trouble shooting this.
I think that you shouldn't use toupper. Why?
Because maybe your professor use invalid input like:
a, 5
and you shouldn't allow lower cases to pass your test.
So in the end your if statement:
if ((row >= 'A' && row <= 'J') && (col > 0 && col < 11))
From your post it is not clear what does not work. You wrote if statement without any compound statement. So what is the criterion that something is wrong?!
For example you could write
if (toupper(row) < 'A' || toupper(row) > 'J' || col < 1 || col > 10) return false;
Take into account that negation of expression
if ((toupper(row) >= 'A' && toupper(row) <= 'J') && (col > 0 && col < 11) )
as it is written by #Ardel is equivalent to
if ( !( ( toupper(row) >= 'A' && toupper(row) <= 'J') && (col > 0 && col < 11 ) ) )
that in turn is equivalent to
if ( !( toupper(row) >= 'A' && toupper(row) <= 'J') || !(col > 0 && col < 11 ) ) )
that is equivalent to
if ( !( toupper(row) >= 'A' ) || !( toupper(row) <= 'J') || !(col > 0 ) || !( col < 11 ) )
that is equivalent to
if ( toupper(row) < 'A' || toupper(row) > 'J' || col <= 0 ) || col >= 11 )
that is at last equivalent to
if (toupper(row) < 'A' || toupper(row) > 'J' || col < 1 || col > 10) return false;
That is your original expression.
So there is no any sense in your post and in the answer of #Ardel.
So I do not understand for example why the answer of #Ardel was uo voted. Maybe it was up voted by whose who is unable to do such conversions as the negation of boolean expressions?:)
I can suppose (moreover after thinking about I am sure) that you should not apply function toupper to the character. For example
if ( row < 'A' || row > 'J' || col < 1 || col > 10) return 0;
The other problem is that you did not say what the function shall do if this condition will be passed successfuly. Maybe inside the function body you should reassign row the following way
row -= 'A';
that to use it as integer value between 1 and 10 inclusively.
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.