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.
Related
What's the differences of if(x==0) vs. if(!x)? Or are they always equivalent? And for different C++ build-in types of x:
bool
int
char
pointer
iostream
...
Assuming there is a conversion from a type to something that supports if (x) or if (!x), then as long as there isn't a DIFFERENT conversion for operator int() than opterator bool(), the result will be the same.
if (x == 0) will use the "best" conversion, which includes a bool or void * converter. As long as there is any converter that can convert the type to some "standard type".
if(!x) will do exactly the same, it will use any converter that converts to a standard type.
Both of these of course assume the converter function isn't a C++11 "don't default convert".
Of course, if you have a class like this:
class
{
int x;
public:
bool operator bool() { return x != 0; }
int operator int() { return x == 0; }
};
then if (x == 0) will do if ( (x == 0) == 0) and if (!x) will will do if (! (x != 0), which isn't the same. But now we're really TRYING to make trouble, and this is VERY BADLY designed code.
Of course, the above example can be made to go wrong with any operator int() that doesn't result in false for x == 0 and true for all other values.
if(!x)
is "if x is not false", that means that in order to evaluate that, you might have to cast x to a bool.
>> This can be harmful and if you wish to avoid it you should use something like the Safe Bool Idiom
if(x!=0)
means "if x is not 0", so that is evaluated comparing x to 0. That might also involve an implicit conversion.
>> Be careful when using pointers this way, C++11 introduces a nullptr to avoid the confusion of NULL==0 (semantically different): What exactly is nullptr?
Take into account what are you going to process
If it is a boolean, the results are pretty clear:
if (!false) // If false TRUE
if (false==0) // If false TRUE
If it is an integer, pay attention to the ! condition
if (0==0) // Unexpected behaviors are missing..
if (!-1) // False
if (! 0) // True
if (! 1) // False
For chars both conditions give me the same results:
if (! ' ') // nothing
if (' '==0) // nothing
if (! 'z') // nothing
if ('z'==0) // nothing
No this all depends on the type of x. For example,
if(cin)
is used in the stl to check if an iostream type hasn't had an error. There is no equivalent cin != 0.
Besides most operators are overloadable and conversions too.
Simply !x will return true for every "false" value (i.e, 0, null, false, etc.) whereas x!=0 will return true, iff x is not equal to 0.
Let's say I had two functions and a variable,
int number;
bool foo (void);
bool footoo (void);
And in each of these functions, some logic with the variable number takes place, such as:
number++;
return(rand()%2);
And then I call them like so:
if (foo() && footoo())
{
cout << "Two foo true!"
}
Why aren't both functions being called and how can I guarantee both functions are called and increment number, regardless of return value?
In C (and included in C++ by default) the && operator is short-circuiting. This means that as soon as the condition is deemed false the other operand is not evalulated. It allows us to do things like if(ptr && ptr->value == 10) without having to do the pointer validity check before the value check in a separate if statement.
If you want to run both functions, run both functions and save off the results:
bool b = foo();
if(foobar() && b)
{
// Stuff
}
Simplest thing I can think of: Assign the return values of both to variables and check those:
bool fooIsTrue = foo();
bool footooIsTrue = footoo();
if(fooIsTrue && footooIsTrue)
// ...
They aren't being called right now because && short-circuits, that is, when the left is false the whole expression is sure to be false so the right side is skipped.
This is useful for constructions where for example you want to first check if you can access something before you check it like so:
if(somePtr != NULL && somePtr[0] == 1)
Why aren't both functions being called? It's called "short-circuit evaluation" and is an efficiency feature of C++. The rationale (roughly) is that code called in the context of a test is generally side-effect-free, and therefore if you can establish that the test is going to fail by only evaluating the leftmost expression, you should do so.
Your code is not side-effect-free, so short-circuit evaluation is not a feature that helps you in this case.
In order to guarantee both functions are called, you'll need to call them separately from the test of their return values:
bool fooRet = foo();
bool footooRet = footoo();
if (fooRet && footooRet)
{
cout << "Two foo true!"
}
In an if statement where && is involved (something like if (a && b && c && d)), if the 1st condition is false, then the rest of the condition in the if isn't evaluated anymore and the false "block" is executed.
The same thing happens with ||. If you have if (a || b || c || d) and a is true, then the rest of the condition isn't evaluated and the true "block" is executed.
If you want both of them to be called, just assign them to two boolean variables like bool myB1 = foo(), myB2 = footoo(); and then do if (myB1 && myB2).
&& and || are what we call short circuit operators. What this means is that if by evaluating the first argument we can tell the truthiness of the whole expression we stop and don't evaluate the next expression.
For example if in this statement a && b is a is false we know the whole statement cannot be true and thus it is ok to stop. With || we can stop if the first statement is true.
If you want both functions to be called the first one must return a value that can be evaluated as true. You can do this if you want both to be called.
bool a = foo();
bool b = footoo();
if (a && b)
{
cout << "Two foo true!"
}
This way both are called.
In C++ bool's are guaranteed to be a 1 or 0 so the bitwise operators are actually the same as the short circuit it terms of the result. However I would not use them for readability.
Becasue with statement if(first && second) , if first is not true, second is not even checked.
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.
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.
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.....