简体   繁体   English

奇怪的程序和调试器if语句行为

[英]Strange program and debugger if statement behavior

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 . 我有一个方法IsCaptured() ,它将枚举状态成员与给定值进行比较并返回一个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: 该方法实现如此,并且m_dragState设置为NONE直到拦截了一个按钮:

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. 我正在运行VS2010 Debug 64位,该程序是一个单线程MFC应用程序。 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)

Ie 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. 即如果满足abs(delta.y) >= thresh.y条件,那么整个if条件的结果根本不依赖于你的IsCaptured()

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. 你的IsCaptured()不一定是真的进步,所以在两个打印输出中很可能都是假的。

You should probably make sure first that the two false's do not refer both to the first trace line. 您应该首先确保两个false不同时引用第一个跟踪线。

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. 如果第二条跟踪线在这里实际打印为假,那么您可能手上有经典的竞争条件,需要防范它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM