Efficiency of using "AND" or "OR" - c

Which is better to use && or ||? For example if I need to check if input is between 5 and 27 and divisible by 3, is it better to check as
if((num < 5) || (num > 27) || (num%3 != 0))
{
//skip
}
else
{
//operations
}
OR
if((num >= 5) && (num <= 27) && (num%3 == 0)
{
//operations
}

Unless you are doing this in an extremely tight loop, you will never notice any difference whatsoever.
Most C compilers will rewrite the expression to take advantage of short-circuit evaluation anyhow, so for those compilers the order is irrelevant (for C++ there are exceptions).
If your compiler cannot optimize the Boolean math (very unlikely in a modern compiler), the second form is better because it allows for some terms to be skipped.

From the CPU's perspective, || and && will more likely than not take exactly the same amount of time to complete. From the compiler's perspective, transforming between the two will be a trivial operation -- this is certainly a choice it will make correctly for you. Use whichever is clearest to you.
It is far more important for you to make good use of C's short circuiting to ensure that the branch is determined in as few executed instructions as possible.

Related

Some confusion with regards to parenthesis in C

Please bear with me, I am trying to learn C as my first programming language and am only 15 minutes in.
Why must parenthesis be used here:
while ((number1 = number2))
...when they do not need to be used here?
while (number1 <= number2)
Thanks in advance.
In:
while (number1 = number2)
number2 is being assigned to number1.
This is optically very similar to comparing number1 and number2, i.e.:
while (number1 == number2)
So a warning is produced in the former case. In order to suppress that warning you need to place the parentheses around the assignment, i.e.:
while ((number1 = number2))
It is a very common mistake to write
if ( a = b ) // assign b to a, branch if result is non-zero
when you meant to write
if ( a == b ) // *compare* b to a, branch if equal
leading to all kinds of mayhem.
It's such a common mistake that most compilers will issue a warning if they see an assignment in a conditional like that. To tell the compiler, "no, I really know what I'm doing", you surround the assignment in an additional set of parentheses:
if ( ( a = b ) )
This basically means, "yes, I intend to assign b to a and branch on the result, shut up."
If I could time travel back to Bell Labs in 1970, this is one of several decisions I'd slap Ritchie over. An entire class of bugs would never have existed if the assignment operator had been := or something equally dissimilar to comparison.
Who said there is a must? You can omit it too.
while (number1 = number2)
yes this would generate compiler warning because you are assigning and checking the assigned value without parentheses. But this is legal and bad practice.
So the reason they did this is to avoid the warning about which the compiler complained. (You shouldn't skip warning to follow a bad practice - rather allow compiler warnings and try to solve them diligently).
Though as you are beginner - aware of the statement, here the while statement is basically
while(number2)
Point: The most common to use would be to while(number1 == number2).
Also does the same thing as the previous one. Who said in the second one you can't? You can.
while ((number1 <= number2))
This is a matter of opinion. Many programmers will still wrap a comparison in parentheses for clarity. That's to make them more legible. For instance:
while(i == 0) //comparison
while(i = 0) //assignment (and therefore, infinite loop)
but more commonly, because chains of conditions can become very hard to read, and getting into the habit of parenthesizing your comparisons makes complex comparisons easier to understand:
//whiskey tango foxtrot
while(i == 0 || j == i && k == 5 || f == "pancakes")
//oh, now it's clear that we're not checking "i && k". Easier to read!
while((i == 0) || (j == i) && (k == 5) || (f == "pancakes"))
//now I've guaranteed i and j both have the value "0" by using parentheses,
//or we get false; but everything is still clearly separated.
while(((i == 0) || (j == i)) && (k == 5) || (f == "pancakes"))
First off, the first example is extremely bad practice. It's not comparing number1 and number2, it's setting the value of number1 to the value of number2. See https://freedom-to-tinker.com/2013/10/09/the-linux-backdoor-attempt-of-2003/ for some more information.
That said, both forms are allowed; you can always add extra parenthesis. In the case you have above, there is no difference.
That said, odds are good that you're simplifying from an example where multiple conditions are chained together, like
while ((number1 == number2) || (number3 == number4))
As you can see, it makes it a bit easier to see what the code is doing. Technically it's not really necessary here, either (though it's generally considered to be good practice), but it can be necessary for more complicated expressions because different expectations about operator precedence can result in your code doing things you might not expect. To take an example from that page, for something like
e = a < d ? a++ : a = d;
It can take a few moments even for an expect to figure out what is going on, and someone less familiar with C will probably need much longer. On the other hand, if you add parenthesis:
e = ( ((a < d) ? (a++) : a) = d );
Things become much easier to read.

Short-circuiting and readability

In this line
if ((last_search == NULL) || (last_search != NULL && total_results != 0))
I know that C's short-circuit evaluation rules say that only if last_search is not null will it try and evaluate the right-hand side of ||, hence it's equivalent to writing
if ((last_search == NULL) || (total_results != 0))
and I was advised to use the later by someone, but still isn't the former more readable? Also won't the compiler optimize out the redundant last_search != NULL?
This is subjective, but no, the first variant is not more readable because there's more to read. The most readable code (and the least buggy!) is that which does not exist. Just think what would happen if you wanted to check 3 or 4 conditions at once.
And here's another counterexample: would you write code like this?
if (number < 0) {
}
else if(number >= 0) {
// why not just "else"?
}
As for performance: the compiler would probably optimize the redundant call away, but undoing the performance degradation does not help with the readability degradation.
No it's not. The second one is a lot more readable. Why would you keep the redundant check in there, regardless of whether the compiler will optimize it away?
The first version tells you that last_search is not NULL because it got there, but if you can't tell that from the first condition (last_search == NULL failed), you've probably got bigger issues than readability.
It is not only the short circuit evaluation that makes it unreadable but also the fact of using superfluous comparisons.
if ( !last_search || total_results)
is much easier to read than anything that you proposed.

Should 'if' test for '==' or '!='

Is there any particular reason for != to be used more than ==?
I have noticed that != seems more common, but wondered if there was a reason for this.
If you have code like this:
if (a == b)
{
// block 1
}
else
{
// block 2
}
It can be rewritten as:
if (a != b)
{
// block 2
}
else
{
// block 1
}
These two examples do the same thing. Neither is more efficient than the other. If one is used more than the other it may be personal preference.
You should use == or != according to the logical condition you are trying to express. If you care about both the true and false conditions, i.e. both the if and else parts then the net effect of switching (if it's a simple comparison) is just which code needs to appear in which part.
There is a coding style, see (the book) Code Complete's section on Forming Boolean Expressions Positively which suggests that boolean expressions that express something positive are easier to understand than those expressing something negative.
If you only care about the condition when it evaluates to true, e.g. you only care when you have equality (for ==) or do not have equality (for !=) then you'll not require an else section if you pick the correct one.
Most of the time the preference of using != or == will depend on the content:
resultOfOperationOrCall = operationOrCall(...);
if (resultOfOperationOrCall != somePredefinedErrorTypeValue) {
// Normal processing
} else {
// Exception/error processing
}
Here using != is logically clearer than using ==
I prefer != because it's more explicit (and there is less chances to write = as mistake).
As assembly code for both == and != present so no issue of efficient or inefficient code for x86 architecture.So it is up to you .you can use any one of them.
if for some machine if assembly code not available then efficient or inefficient comes it to picture as that is achieved by compiler by performing some additional operation(that is adding additional assembly code).
Its wholly and solely depends on the perception & need of user. I don't see any reason on why would one use != more than ==

One line assignment according condition in c/c++

Hi,
i would like to know which one of these assignments is faster, safer, better etc. and possibly why:
int choice = fgetc(stdin);
unsigned int bSize;
choice = fgetc(stdin)
1:
bSize = (choice == 'y' || choice == 'Y') ? 256 : 128;
2:
bSize = 128 + ((choice == 'y' || choice == 'Y') << 7);
Thanks.
Regarding speed, this would be at least as fast as choice 2:
bSize = 128 << (choice == 'y' || choice == 'Y');
Whether that would be faster than choice 1 is not immediately obvious to me. However, for tuned performance on an unknown platform, I think that I like the suggested variant on choice 2. The reason is that, at the hardware level, choice 2 (original or variant) does not involve reloading the program counter, but invokes a relatively straightforward shift-register operation, involving relatively few transistors. (Actually, if you want to get really technical about it, I am given to understand that the shift is probably accomplished by multiplexing. To detail that would be too much for the present format, but the point is that the output of (choice == 'y' || choice == 'Y') is effectively piped straight to one of the multiplexer's control lines. Anyway, it's really fast.)
Regarding whether one can safely use the evaluated condition in the manner suggested, ISO/IEC 9899:1999 (E), sect. 6.5.14.3, guarantees that one can safely do this. It reads, "The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int."
(#PaulR rightly observes that electronic-theoretical considerations like the ones this answer offers are not decisive. One must profile actual code on an actual platform to tell for sure which is faster. Nor is this a mere quibble on #PaulR's part. It is all well to argue that choice 2 would be faster, but this does not mean that is is faster. Depending on the CPU in use, branch-predicting or other hardware could promote choice 1, nor would I be extremely surprised if it did.)
In my opinion 'Choice 1' is 'faster' because there's only one assignment operation done after the comparison. In 'Choice 2' it does '+' and '<<' along with the comparison part. 'Choice 1' is 'safer' because it is more readable than the other choice so programmer will have less chance to do error in writing it. Choice 1 is 'better' because of the previous two reasons.

Idiomatic way to check for non-zero

When I wish to check if a value is 0 in C, how is it idiomatically done?
if (!num)
if (num == 0)
While this is a matter of taste, I find it pretty much depends on intention. If the value is to be used as a boolean, ! is alright. If the value is counting something the equality makes more sense.
if (!isVisible) {...}
if (isVisible == 0) {...} // Intention not as clear as line above.
if (numberOfItems == 0) {...}
if (!numberOfItems) {...} // Intention not as clear as line above.
I always prefer the second way:
if (num == 0)
As num == 0 or ptr == NULL evaluates to a boolean which is the intent. The Java compiler enforces this form, but C/C++ compilers don't.
The worst example of this would be:
if (!strcmp(str, "something"))
Which really disguises its intent as the strcmp family of functions don't return boolean, they return positive, zero, or negative (as pointed out by #JoachimPileborg).
However if the int is being used to represent a boolean type, which C does not have a builtin type for, then this form is OK:
if (!b)
But this can be made self documenting by creating a custom type:
typedef int bool;
#define true 1
#define false 0
bool b = true;
if (!b)
{
... etc
}
Whatever the others told you WITH AN EXCEPTION!
Don't do it with float and double. IEEE 754 floats/doubles/long doubles (the most commonly used) often don't contain exact values, so comparing them directly with 0 is foolish (or doing if (!floatValue))
Example: http://ideone.com/PIUflA
float f = 0.3;
f -= 0.2;
f -= 0.1;
if (!f)
{
printf("zero\n");
}
else
{
printf("non zero\n");
}
if (f == 0)
{
printf("zero\n");
}
else
{
printf("non zero\n");
}
With unoptimized compilation can return (on ideone does)
non zero
non zero
(if you enable optimizations, the compiler could pre-compute some values in higher precision and round them to 0)
I think it depends on the context. If the variable refers to a boolean value is better first choice. Otherwise, the second is better.
It's done however you want it to be done, in terms of your style. I don't see it as mattering as long as your consistent and it's clear on what you're trying to do, or if you do it in cases where it may flow better in an English sentence and may put emphasis on what your doing.
For sake of clarity I usually have if (num == 0), since it takes less thinking to understand what I'm doing when I'm going over my code.
!!value will work too if you want to check if value is non-zero.
!value evaluates to 1 when value=0 and 0 when value≠0.
The second ! flips it, making !!value evaluate to 1 when value≠0 and 0 when value=0.
We may argue which way is better, but idiomatic, though for what I can tell by other answers archaic, would be if(!num).
For the compiler, it does not matter, of course. For the human reader it does. Since both forms are used by other human beings, you should get used to them and recognise them. Personally, I prefer the shortest form, which takes less time (less tokens, especially parenthesis) to read and understand. Especially:
if (!ptr) {}
if (!strcmp(a,b)) {}
are easyer to read than
if (ptr != NULL) {}
if (strcmp(a,b) == 0) {}
if (0 == strcmp()) {}
The last form makes me physically sick.

Resources