I was wondering if one is inefficient over the other (two codes below)?
if ( abc & myType == myType )
{
if (myValue)
{
// do something
}
}
OR
if ( (abc & myType) && myValue )
{
// do something
}
They are not equivalent, a "corrected" second one would be
if ( (abc & myType == myType) && myValue )
{
// do something
}
In this case, any decent compiler will emit the same code for both.
Also, it's almost never sensible to do this kind of micro-optimization - you waste time around a difference that will be at most of one or two assembly instruction, maybe even in a code path that isn't critical. Here, where there's no real difference in performance, the real optimization to do is towards clarity of your code.
Real optimization is about not caring about these micro-differences (which are probably already taken of by the compiler), and instead profiling the code to find the real bottlenecks.
A few others have pointed out that the two are not equivalent for this reason:
if (abc & myType == myType )
{
if (myValue) {}
}
// OR
if ( (abc & myType) && myValue ) // missing myType == myType
{}
However there is a second reason the two are not equivalent: the == operator has higher precedence than the & operator (see this link). Your first expression therefore evaluates as follows:
if (abc & myType == myType) // Evaluates to (abc & true)
{
if (myValue) {}
}
You probably intended this:
if ((abc & myType) == myType) // Now the bitwise and happens before
// the comparison is made
{
if (myValue) {}
}
To avoid exactly this kind of bug, I always use parentheses to enforce precedence any time there is any possibility of ambiguity from a human's perspective (even though the compiler will never find it ambiguous), on the assumption that the reader has no clue what the actual precedences are. This has the added benefit of making the code easier to read.
Related
Consider the following code:
if (ptr == nullptr || really long conditional that depends on ptr existing || another really long conditional)
// do stuff
Due to how C++ evaluates conditionals, I consider this elegant and great, except for the fact that there are really long conditionals involved. The style guide that I follow suggests I break up this statement in const bools like the following:
const bool a = really long conditional that depends on ptr not being nullptr
const bool b = another one
if (ptr == nullptr || a || b)
// do stuff
Now this is obviously going to throw an exception when ptr is nullptr. So to escape this scenario I'd maybe write something like this.
if (ptr == nullptr)
// do stuff
const bool a = really long conditional that depends on ptr not being nullptr
const bool b = another one
if (ptr == nullptr || a || b)
// do stuff
Even if we wrap the stuff we're doing in // do stuff in a function, we'd still be calling the function twice which is not very elegant.
What are my options here? Can I delay the evaluation of these const bool variables? Do I define and undef them? Or do we consider this an edge case that should be handled like the first piece of code in this post?
This should do it, if you really want to do it that way. It only evaluates the conditionals for the cases where they're used, setting them to false otherwise:
const bool a = (ptr == nullptr) ? false : really long conditional ...
const bool b = (ptr == nullptr || !a) ? false : another one;
However, since this is primarily a code formatting issue at heart, I'd suggest you just do something like (easily readable, in my opinion):
if (ptr == nullptr ||
really long conditional that depends on ptr existing ||
another really long conditional)
{
// do stuff
}
This removes the need for temporary variables and the more complex evaluation/use of them, and nothing in the standard states that if statements need to be on a single line :-)
I'd suggest:
if ( ptr == nullptr || cond1(ptr) || cond2(ptr) )
{
where cond1 and cond2 could be free functions or lambdas that perform the "really long conditional" test and have meaningful names.
I want to declare a local variable in the brackets of an if statement.
For example.
if((char c = getc(stdin)) == 0x01)//This is not OK with g++.
{
ungetc(c, stdin);
}
What I want is, to see if the character is the one I want.
To say it commonly, I want to use the variable(char c) both in the line of if and the body of if, but not outside the if.
But g++(GCC 4.8.1) says expected primary-expression before 'char'.
I wonder if there's a way to do that, because I don't want something like
char c = getc(stdin);
if(c == 0x01)
{
bla...
}
If it's the namespace pollution you are worrying about you can always define the if statement within a block:
{
char c = getc(stdin);
if(c == 0x01)
{
// ...
}
}
So that c will only last until the end of the block is reached.
I didn't know how to create a variable and test its value with an if until after seeing some of the posted solutions. However, you could use switch. This would allow you to react to additional values (perhaps EOF):
switch (int c = getc(stdin)) {
case 0x01: ungetc(c, stdin); break;
case EOF: // ...handle EOF
default: break;
}
You could always place the if statement in an inlined function instead, and the code will look a little cleaner. If you really want the source code right at that location, but without creating a new scope around an if with a new variable, then perhaps a lambda would be acceptable to you.
[](int c){ if (c == 0x01) ungetc(c, stdin); }(getc(stdin));
Since you are only comparing against one valuem your particular problem does not require a variable at all, so you can simply do:
if (getc(stdin) == 0x01) {
char c = 0x01;
ungetc(c, stdin); //or bla...
}
If you are wanting to compare against a set of values, then the switch suggestion is the better option.
Jerry Coffin's solution looks appealing, but it really boils down to:
if (int c = (getc(stdin) == 0x01)) //...
This is probably not what you really wanted, as it does not generalize well if you want to compare to a value different from 0x01.
Potatoswatter's solution seems closer to what you want, but perhaps it would be nicer to pull the type out into a standalone class:
template <typename T>
class SetAndTest {
const T test_;
T set_;
public:
SetAndTest (T s = T(), T t = T()) : set_(s), test_(t) {}
operator bool () { return set_ == test_; }
operator bool () const { return set_ == test_; }
operator T & () { return set_; }
operator T () const { return set_; }
};
//...
if (auto c = SetAndTest<int>(getc(stdin), 0x01)) {
ungetc(c, stdin); //or bla...
}
You can define the variable inside the if statement just fine. For example, this should compile:
if (int ch = getchar())
;
The problem is that the type (e.g., int) must follow immediately after the opening parenthesis. The extra parenthesis you have is what's causing compilation to fail. So, if you really want to do this, you'll need to get a little clever and use something like this:
if (char ch = 0 || ((ch = getchar()) == 0x1))
This lets you get the creation and initialization of ch done, then after that part of the expression is complete, put in the parentheses around the ch=getchar() to override the precedence of assignment vs. comparison.
Note that && and || do short-circuit evaluation, so you need to be careful with your initialization. You can use either:
if (char ch = 0 || ...
...or:
if (char ch = 1 && ...
...but if you try to use if (ch = 1 || ... or if (ch = 0 && ..., the short-circuit evaluation will keep the right operand (the part you really care about) from being evaluated at all.
Now the caveat: while I'm reasonably certain this code fits the standard's requirements, and most (all?) current compilers will accept it, it's likely to cause most programmers reading the code some serious head-scratching figuring out what you've done, and why. I'd be extremely hesitant (at best) about using this "technique" in real code.
Edit: It's been pointed out that the result from this may be even more misleading than some initially expect, so I'll try to clarify the situation. What happens is that a value is read from input. That value is assigned to ch and compared to 0x1. So far so good. After that, the result of the comparison (converted to an integer, so either 0 or 1) will be assigned to ch. I believe it has sufficient sequence points that the result is defined behavior. But it's probably not what you, or anybody, want -- thus the advice that you probably don't want to use this, and the mention that it would probably leave most programmers scratching their heads, wondering what you were trying to do. In the very specific case of comparing to 0x1, the value of ch inside the if statement will be 1, but it's more or less a coincidence. If you were comparing to 0x2, the value of ch inside the if would still be 1, not 2.
Ran across some code that used this, which led me to wonder.
if(condition) foo = bar();
condition && (foo = bar());
Are these two segments of code equal to a compiler? If not, in what ways would they differ?
Due to operator precendence, the latter is interpreted as:
(condition && foo) = bar();
Additionally, there is a possibility of && being overloaded, which may result in pretty much anything.
So in short: they are not equal at all - at least in general case.
The first version is just a plain old statement.
The second version is an expression that will return the result of the entire expression. That probably allows some tricky one-line syntax that, as per usual, could potentially make code more readable but will more likely make it more complex and harder to parse quickly due to unfamiliarity.
IMO either use it everywhere consistently so that readers of your code get used to it, or don't use it at all.
Unless && is overloaded for the combination of types of condition and foo they will have identical behavior - the latter will work this way:
bool result;
if( !condition ) {
result = false;
} else {
foo = bar();
result = foo != 0;
}
and result gets ignored
that's usual short-circuiting - if the first component of && is false the second is not evaluated.
IMO the second variant is much less readable.
Unless condition && foo evaluates to an lvalue , condition && foo = bar(); is meaningless.
There is a compiler error: invalid l-value. To have same functionality you must use
conticion ? foo = bar( ) : <other accion>;
If && is not overloaded for neither condition nor foo:
condition && (foo = bar());
will be treated as
(condition.operator bool()) && (foo = bar());
if (condition.operator bool()) isn't true, (foo = bar()) won't be executed and vice versa.
In either C or C++, is there a conclusive difference between using !(variable) and (!variable) in an if-statement, such as:
if (!(variable)) { .. // do something }
or
if (!variable && !(variable2)) { .. // do something }
such that one version delivers a different result over the other?
Its all about order of operation. Using !(variable) will evaluation all conditions inside of the parenthesis then do the ! (or NOT) to determine whether to enter the if statement where-as (!variable will do the NOT specifically on the variable itself.
So in the situations:
!(true && false) = true
!(true && true) = false
(!true && !false) = false
(!true && true) = false
!(true && !false) = false
...and so on
Hope this helped.
The only way it would make a difference is if the variable is an expression, then its a matter of operator precedence. Otherwise && has lower precedence than !
There is no difference between
!(variable)
and
(!variable)
but if you are using operators that has different precedence you will have a difference. For example, if you write
!(varible1 && variable2)
is not the same as
!varible1 && variable2
because the NOT will be applid to the whole operation in the first case and only to varible1 in the second case.
May be you are getting a problem with the evaluation, C has lazy evaluation, so when the execution detects that boolean evaluation has a result, it doesn't try the other values. So, now consider instead of variables you have functions.
int foo() { printf("foo\n"); return 1; }
int bar() { printf("bar\n"); return 0; }
If you write
if (foo() && bar()) { ... }
you will get
foo
bar
but if you write
if (bar() && foo()) { ... }
you will only get
bar
because the evaluation will be false, doesn't matter the result of foo
No, in your example the first one (although the parens are unbalanced :)) behaves exactly like it would if there were no parentheses, and the second behaves the same way. You can even do this
if ((!((((variable)))))) { ... }
But don't :)
They should never evaluate to different things. Parentheses used this way are really for grouping operations, but in this case, you're not grouping any operations, just the expression itself.
So !(x) is just a pedantic way of writing !x
Now, if you had an operation inside the parentheses, that's where the differences start.
I'm currently working with the Diab 4.4 C++ compiler. It's a total POS, non ANSI-compliant, and I've found problems with it in the past.
I'm wondering if the following problem is an issue with the compiler, or a shortcoming in my knowledge of C++
I realize that the form of x = x && y; will short-circuit the y part if x is false. What the compiler is doing is short-circuiting in the case of x = x && y(); where y() is a non-const function.
class A
{
int _a;
A(int a) { _a = a; }
bool someFunction() { _a = 0; return true; }
};
main(...)
{
A obj = A(1);
bool retval = false;
retval = retval && A.someFunction();
/* What is the value of A._a here? */
}
What seems wrong to me is the fact that the compiler is doing this short-circuiting even though someFunction() is not a const function. If it's not const, is the compiler overstepping its bounds by skipping A.someFunction() when retval is false?
Also, I realize this issue can be avoided by writing retval = A.someFunction() && retval; but I'd really like to know why this is happening.
Short circuiting applies to all expressions, regardless of const-ness. Skipping the call to someFunction() is correct.
The && and || operators are defined to evaluate lazily, this is the way the language works. If you want the side effects to always happen, invoke the function first and stash the result, or refactor the function to split the work from the state query.
As others have explained, || and && always perform short-circuit evaluation.
Also note that short-circuit evaluation can be very useful, since it lets you write code like this:
retval = obj_pointer && obj_pointer->SomeBooleanMethod();
Without short-circuit evaluation, this would crash on a NULL pointer.
It doesn't matter if the second operand to && is const or not. After the first operand evaluates to false the return value is known, so there's no reason to evaluate the second operand.
If the function has side effects that require it to be executed, put it first.
Short-circuit evaluation has nothing to do with const or non-const. It happens no matter what.
The statement A() && B(); will do exactly what if (A()) B(); does (although it isn't a perfect substitute, as the second one allows an else). This is sometimes used to change a statement into an expression (such as when writing a macro, or embedding it in another statement).
The && operator is also called the shortcut operator, which means it only evaluates the second part if the first part returned true. That's the main difference between && and &:
value = func1() && func2(); // evaluates func2() only if func1() returns true
value = func1() & func2(); // evaluates both func1() and func2()
For && operator,
1 && X = X
0 && X = 0
so in case first var is 0, compiler will evaluate the expression to 0, no question, what ever the X is.
Compiler will ignore the X part as it wont impact the result. Here X can be any thing function/variable/expression.....