Strange program and debugger if statement behavior - c++

This is a sanity check because I've lost mine.
I have a method IsCaptured() which compares an enum state member to a given value and returns a bool. I use this in conjunction with a mouse threshold check to determine if a drag begin message should be sent and a drag operation begun. The problem is this is being triggered on mouse move when it shouldn't be. I've added trace messages as follows:
TRACE(L"%s\n", (IsCaptured()) ? L"true" : L"false");
CPoint delta = pt - m_trackMouse;
static CPoint thresh(GetSystemMetrics(SM_CXDRAG), GetSystemMetrics(SM_CYDRAG));
if (IsCaptured() &&
abs(delta.x) >= thresh.x || abs(delta.y) >= thresh.y)
{
TRACE(L"%s\n", (IsCaptured()) ? L"true" : L"false");
// Send message to enter drag mode
bool bDrag = ::SendMessage(m_trackWnd, WM_DD_BEGIN, ::GetDlgCtrlID(m_trackWnd), (LPARAM)(void*)&m_info) != 0;
// ...
}
Now the strange part, the output:
false
false
The method is implemented like so and m_dragState is set to NONE until there is a button down intercepted:
enum { NONE, CAPTURED, DRAGGING };
bool IsCaptured() const { return m_dragState == CAPTURED; }
I've tried rebuilding the entire solution to no avail. I'm running VS2010 Debug 64-bit and the program is a single threaded MFC app. What the $##! is going on here?

There's nothing strange in your output. && has higher precedence than ||, which is why your
if (IsCaptured() &&
abs(delta.x) >= thresh.x || abs(delta.y) >= thresh.y)
is interpreted as
if ((IsCaptured() && abs(delta.x) >= thresh.x) ||
abs(delta.y) >= thresh.y)
I.e. if the abs(delta.y) >= thresh.y condition is met, then the result of the entire if condition does not depend on your IsCaptured() at all.
The compiler does not care that you "expressed" your intent in line breaks. Operator precedence matters. Line breaks don't.
What you apparently were intending to do was
if (IsCaptured() &&
(abs(delta.x) >= thresh.x || abs(delta.y) >= thresh.y))
Note the placement of extra braces around the operands of || subexpression.

Think of this as:
(IsCaptured() && abs(delta.x) >= thresh.x || abs(delta.y) >= thresh.y)
this:
(false && true) || true
Your IsCaptured() doesn't have to be true to progress, so it can quite possibly be false in both printouts.

You should probably make sure first that the two false's do not refer both to the first trace line.
If the second trace line is actually printing false here, you probably have a classic race condition on your hands and need to protect against it.

Related

Is it good practice if container's size is validated and accessing an element under same conditional statement?

Which one of the following code is more preferable between two of them and why?
1.
std::stack<int>stk;
//Do something
if( stk.empty() == true || stk.top() < 10 )
{
//Do something.
}
or
2
std::stack<int>stk;
//Do something
if( stk.empty() == true )
{
//Do something.
}
else if( stk.top() < 10 )
{
//Do something.
}
Builtin operators && and || perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first). So, expression stk.empty() || stk.top() < 10 is safe and good practice, stk.top() is only called if stk.empty() evaluates to false. In other words, the operators were designed to enable such usage.
It entirely depends on the use case. In the first code, you have an OR condition for empty stack and checking the value of element if an element exist. So, it's clear and you can proceed with the code.
In the 2nd code, you want to execute something different for both the conditions. Hence you have put the conditions in a if else loop.
Good practise comes into sense when you don't want your code to break or pass corner test cases.You might not wan't something in your code when the stack is empty.
std::stack<int>stk;
if(stk.top() < 10 )
{
//Do something.
}
else if(stk.empty() == true)
{
//Do something
}
This will generate run time error since the stack is empty but you are accessing top element before checking the stack empty condition.
Snap of the error
I hope the answer makes it clear.

C++ setGender method reverts to default values

I've written the code bits below. I have a constructor which takes five arguments. Unfortunately, the setGender method spits out a default 'M' for all instances of a class rather than setting the gender to the specified parameter. What am I doing incorrectly? Any advice would be greatly appreciated. Thank you.
DateProfile::DateProfile(char gdr,
char searchGdr, int romanceScale, int financeScale, string theName)
bool DateProfile::setGender(char gdr)
{
if (gdr != 'M' || gdr != 'F')
return false;
gender = gdr;
return true;
}
if (gdr != 'M' || gdr != 'F') is always true, irrespective of input. If you're passing 'M', the second part of the expression is true. If you're passing anything else, the first part of the expression becomes true.
What you meant to write is if (gdr != 'M' && gdr != 'F') instead.
Increasing the warning level of your compiler may have helped you spot the error. Most compilers will warn about expressions always evaluating to a single value, or at least about the unreachable code following it.

Can someone please check my timer program in C++

I want to write a program that checks if the changes in the values of X,Y and Z don't exceed a difference of 10 within 5 seconds, the initialValues() function should be called.
I have written the following program but it crashes while running and the program doesn't work. Then I have to force close the program.
below is the main part of my program for timer. My program doesn't crash when I remove this specific part.
How do I fix this?
while(X<=X+10 || X>=X-10 && Y<=Y+10 || Y>=Y-10 && Z<=Z+10 || Z>=Z-10)
{
clock_t t;
t = clock();
t = clock()-t;
float timer = t/CLOCKS_PER_SEC;
if(timer==5)
{
initialValues(X,Y,Z);
cout<<"X = "<<initialX<<" Y = "<<initialY<<" Z = "<<initialZ<<endl;
}
}
You don't say what the function initialValues does, so we cannot know whether something dodgy is done there.
However, it seems likely that you have an infinite loop. Check the conditions in the while loop, and insert brackets to separate conditions that should be evaluated together, such as, for exmaple:
while( ( X<=X+10 || X>=X-10 ) && ( Y<=Y+10 || Y>=Y-10 ) && ( Z<=Z+10 || Z>=Z-10) )
Note the extra brackets.
In particular, you should check whether the conditions that you have specified are always true, as suggested by another user. It seems to me that X<=X+10 always, and the same applies to the rest of conditions.

if condition on turbo C++

I'm having a problem regarding with if statement in C++ this statement is in do-while loop.
gotoxy(27,22);cout<<"Do you want to continue [Y]?";
sub=getche();
if(sub!='y' || sub!='Y')
{
gotoxy(27,24);cout<<"INVALID ANSWER!!";
gotoxy(27,26);cout<<"Closing Program....";
delay(3000);
exit(1);
}else
{
sub=ans;
}
}while(tolower(ans)=='y');
whenever I input y on the variable sub the code on if statement is still executing.. please someone tells me where is the error.. Thanks!
The boolean expression of (sub!='y' || sub!='Y') will always evaluate to true
This line:
if(sub!='y' || sub!='Y')
Needs to be this:
if ( (sub != 'y') && (sub != 'Y') )
Your code if(sub!='y' || sub!='Y') will be true ,no matter what you enter because eithersub!='y' or sub!='Y' will evaluate to true. Hence Use && instead of ||.

C++ boolean logic error possibly caused by if statements

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.