C++ boolean logic error possibly caused by if statements - c++

Here is an extremely simplified version of a section of code that I am having trouble with.
int i = 0;
int count = 0;
int time = 50;
int steps = 1000;
double Tol = 0.1;
bool crossRes = false;
bool doNext = true;
for (int i=0; i<steps; i++) {
//a lot of operations are done here, I will leave out the details, the only
//important things are that "dif" is calculated each time and doNext either
//stays true or is switched to false
if (doNext = true) {
if (dif <= Tol) count++;
if (count >= time) {
i = steps+1;
crossRes = true;
}
}
}
if (crossRes = true) {
printf("Nothing in this loop should happen if dif is always > Tol
because count should never increment in that case, right?");
}
My issue is that every time it gets done with the for loop, it executes the statements inside the "if (crossRes = true)" brackets even if count is never incremented.

You've made a common (and quite frustrating) mistake:
if (crossRes = true) {
This line assigns crossRes to true and returns true. You're looking to compare crossRes with true, which means you need another equals sign:
if (crossRes == true) {
Or more concisely:
if (crossRes) {

I stand corrected:
if (crossRes)
You wouldn't have this problem if your condition was
if (true = crossRes)
because it wouldn't compile.
`crossRes = true` always evaluates to `true` because it's an assignment, to `true`.
You want `crossRes == true`:
if (crossRes == true) {
printf("Nothing in this loop should happen if dif is always > Tol
because count should never increment in that case, right?");
}

= is assignment, == is equality comparison. You want:
if (crossRes == true) {
You make the same mistake here:
if (doNext = true) { // Bad code

The other answers here have told you the problem. Often your compiler will warn you but a way to ensure that you do not do this is to put the constant term on the left
true == crossRes
that way you get a compiler error instead of a warning and so it can't escape unnoticed since
true = crossRes
wont compile.

First, although a number of people have pointed to the problem with if (crossRes = true), for some reason they haven't (yet, anyway) pointed to the same problem with if (doNext = true).
I'll stick to pointing out that you really want if (crossRes) rather than if (crossRes == true) (or even if (true == crossRes)).
The first reason is that it avoids running into the same problem from a simple typo.
The second is that the result of the comparison is a bool -- so if if (crossRes==true) is necessary, you probably need if (((((crossRes == true) == true) == true) == true) just to be sure (maybe a few more -- you never know). This would, of course, be utterly silly -- you're starting with a bool, so you don't need a comparison to get a bool.
I'd also note for the record, that if you insist on doing a comparison at all, you should almost always use if (x != false) rather than if (x == true). Though it doesn't really apply in C++, in old C that doesn't have an actual Boolean type, any integer type can be used -- but in this case, a comparison to true can give incorrect results. At least normally, false will be 0 and true will be 1 -- but when tested, any non-zero value will count as equivalent to true. For example:
int x = 10;
if (x) // taken
if (x == true) // not taken, but should be.
If you're not starting with a Boolean value as you are here, then the if (<constant> <comparison> <variable>) makes sense and is (IMO) preferred. But when you're starting with a Boolean value anyway, just use it; don't do a comparison to produce another of the same.

Related

Is there a way of doing a "post switch" like operation with bool?

I have a condition like the following where I just want to have the second bool be the trigger for a single time, since this condition is invoked relatively often I don't like the idea of doing the assignment of it being false every time the condition is true so, I tried to take advantage of the order of logical AND and OR and the post increment operator. But it appears to work don't do what I expected it to do. So is there a way to make a post state switch for this line?
where firstTitleNotSet is:
bool firstTitleNotSet;
if (titleChangedSinceLastGet() || (p_firstTitleNotSet && p_firstTitleNotSet++))
The idea is that the first part is the primary trigger and the second is the trigger that only has to trigger the first time.
While I easily could do
if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
firstTitleNotSet = false;
//...
}
I don't like this as it is reassigning false when ever the conditional block is invoked.
So is there some way of "post change" the value of a bool from true to false? I know that this would work the other way around but this would negate the advantage of the method most time being the true trigger and therefor skipping the following check.
Note: The reasons for me making such considerations isntead of just taking the second case is, that this block will be called frequently so I'm looking to optimize its consumed runtime.
Well, you could do something like:
if (titleChangedSinceLastGet() ||
(p_firstTitleNotSet ? ((p_firstTitleNotSet=false), true):false))
An alternative syntax would be:
if (titleChangedSinceLastGet() ||
(p_firstTitleNotSet && ((p_firstTitleNotSet=false), true)))
Either one looks somewhat ugly. Note, however, that this is NOT the same as your other alternative:
if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
p_firstTitleNotSet = false;
//...
}
With your proposed alternative, pontificate the fact that p_firstTitleNotSet gets reset to false no matter what, even if the conditional was entered because titleChangedSinceLastGet().
A more readable way than the assignment inside a ternary operator inside an or inside an if would be just moving the operations to their own statements:
bool needsUpdate = titleChangedSinceLastGet();
if(!needsUpdate && firstTitleSet)
{
needsUpdate = true;
firstTitleSet = false;
}
if(needsUpdate)
{
//...
}
This is likely to produce very similar assembly than the less readable alternative proposed since ternary operators are mostly just syntactic sugar around if statements.
To demonstrate this I gave GCC Explorer the following code:
extern bool first;
bool changed();
int f1()
{
if (changed() ||
(first ? ((first=false), true):false))
return 1;
return 0;
}
int f2()
{
bool b = changed();
if(!b && first)
{
b = true;
first = false;
}
return b;
}
and the generated assembly had only small differences in the generated assembly after optimizations. Certainly have a look for yourself.
I maintain, however, that this is highly unlikely to make a noticeable difference in performance and that this is more for interest's sake.
In my opinion:
if(titleChangedSinceLastUpdate() || firstTitleSet)
{
firstTitleSet = false;
//...
}
is an (at least) equally good option.
You can compare the assembly of the above functions with this one to compare further.
bool f3()
{
if(changed() || first)
{
first = false;
return true;
}
return false;
}
In this kind of situation, I usually write:
bool firstTitleNotSet = true;
if (titleChangedSinceLastGet() || firstTitleNotSet)
{
if (firstTileNotSet) firstTitleNotSet = false;
//...
}
That second comparison will likely be optimized by the compiler.
But if you have a preference for a post-increment operator:
int iterationCount = 0;
if (titleChangedSinceLastGet() || iterationCount++ != 0)
{
//...
}
Note that this will be a problem if iterationCount overflows, but the same is true of the bool firstTitleNotSet that you were post-incrementing.
In terms of code readability and maintainability, I would recommend the former. If the logic of your code is sound, you can probably rely on the compiler to do a very good job optimizing it, even if it looks inelegant to you.
That should work:
int firstTitleSet = 0;
if (titleChangedSinceLastGet() || (!firstTitleSet++))
If you wish to avoid overflow you can do:
int b = 1;
if (titleChangedSinceLastGet() || (b=b*2%4))
at the first iteration b=2 while b=0 at the rest of them.

Testing - acheving condition coverage with nested if's?

I am trying to find out if it's possible to have a set of test inputs that achieves 100% condition coverage for the following code.
bool a = ...;
bool b = ...;
if (a == True){
if (b == True && a == False){
...
} else{
...
}
} else{
...
}
However, most of the resources I have found only deal with one condition. Therefore I am not sure what to do with nested ifs. Specifically, I am not sure what to do with the second if statement. Since "a == False" should never be true given the outer if statement, is it correct to say that this code can never have 100% condition coverage test cases?
No, it's not possible: (b == True && a == False) will never be true, since it's inside a block
if (a == True)
a can't be true and false at the same time. Either there is a bug, or you have dead code that should simply be removed. And then, you can have 100% coverage.

Logical error with the || operator?

A part of my program (I can add more details if necessary) contains this line:
if((e->start->explored = false) || (e->end->explored = false)){
//do action...
}
This is part of a graph algorithm, where e is a directed edge with incident vertices "start" and "end." I would like the 'action' to happen if at least one of the incident vertices of e is unexplored, but this logic appears to be faulty. Although I used a small example and verified that, indeed, the start and end vertices of my edges were unexplored to start with, my overall function is going into an infinite loop.
So then I tested it like this:
if((e->start->explored = false) || (e->end->explored = false)){
//do action...
}
else cout << "FAIL";
...and, of course, it printed a screen of "FAIL." What is my logic error here?
You're assigning false to your properties instead of testing them against false. This is a mistake often made, and quite hard to debug. Change your = assignment operator to the equality operator ==:
if((e->start->explored == false) || (e->end->explored == false)) {
// Do action...
} else {
cout << "FAIL";
}
Instead of comparing the values to false, it's clearer to use the ! not operator instead. The inner brackets are done away with, too:
if(!e->start->explored || !e->end->explored) {
// Do action...
} else {
cout << "FAIL";
}
As the others have expounded you accidentally used assignment instead of comparison. However, the real solution is not to compare at all:
Comparing bool values to literals true and false is nonsensical!
Instead, write:
if(! e->start->explored || ! e->end->explored)
You have used the assignment operator = not the comparison operator ==.
You are assigning values here:
if((e->start->explored = false) || (e->end->explored = false)){
Should be:
if((e->start->explored == false) || (e->end->explored == false)){

How do I use std:vector's erase() function properly?

I am having a strange issue when using the erase() function on a std:vector. I use the following code:
int count = 0;
for (int itr=0; itr<b.size(); ++itr) {
if (b[count].notEmpty = false) {
b.erase(b.begin()+count);
--count;
}
++count;
}
However, for some reason there are no elements actually getting erased from b. b is declared elsewhere as follows:
vector<block_data> b;
Where block_data is a structure, and contains the boolean value notEmpty. Some of b's elements are properly being assigned with notEmpty = false earlier in the code, so I am not sure why they aren't getting erased. Is it an error with the syntax, or something else?
There's nothing wrong with your use of erase. The problem is an assignment inside the if condition:
if(b[count].notEmpty = false)
This sets b[count].notEmpty to false, then returns false. This will cause the inner-body of the if-statement to never run.
Change it to
if(b[count].notEmpty == false)
or event
if(!b[count].notEmpty)
And you should be good to go.
Others have pointed out how to fix your code, but just in case: how to use a Standard algorithm.
// Decide if an element is to be removed
auto predicate = [](block_data& b)
{
// more idiomatic than b.notEmpty == false
return !b.notEmpty;
});
// Remove
auto removed = std::remove_if(b.begin(), b.end(), predicate);
// Count
auto count = b.end() - removed;
// Erase.
b.erase(removed, b.end());
b[count].notEmpty = false should be b[count].notEmpty == false, otherwise the if will always be false.
Better practice to write false == b[count].notEmpty, in this way the constant on the left is not an l-value, and if you make the (quite common) mistake of writing = instead of == you'll get a compilation error.

Boost lambda bewilderment

Why is callback called once only?
bool callback()
{
static bool res = false;
res = !res;
return res;
}
int main(int argc, char* argv[])
{
vector<int> x(10);
bool result=false;
for_each(x.begin(),x.end(),var(result)=var(result)||bind(callback));
return 0;
}
The || expression short circuits after the first time bind returns true.
The first time you evaluate
result = result || bind(...) // result is false at this point
bind is called, because that's the only way to determine the value of false || bind(...). Because bind(...) returns true, result is set to true.
Every other time you say
result = result || bind(...) // result is true at this point
... the bind(...) expression isn't evaluated, because it doesn't matter what it returns; the expression true || anything is always true, and the || expression short circuits.
One way to ensure that bind is always called would be to move it to the left side of the ||, or change the || to an &&, depending on what you are trying to accomplish with result.
In your particular example, Boost.Lambda doesn't really gain you anything. Get rid of the lambda parts, and maybe you'll see more clearly what's going on:
for (int i = 0; i < 10; ++i)
result = result || callback();
This still relies on you to know that the || operator is short-circuited, as Daniel explained.