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

Strange program and debugger if statement behavior

本文关键字:if 语句 调试 程序      更新时间:2023-10-16

这是一个完整性检查,因为我丢失了我的。

我有一个方法IsCaptured(),它将枚举状态成员与给定值进行比较,并返回bool。我将此与鼠标阈值检查结合使用,以确定是否应该发送拖动开始消息并开始拖动操作。问题是,这是触发鼠标移动时,它不应该是。我添加了如下跟踪消息:

TRACE(L"%sn", (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"%sn", (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;
    // ...
}

现在奇怪的部分,输出:

false
false

方法是这样实现的,m_dragState被设置为NONE,直到有一个按钮被拦截:

enum { NONE, CAPTURED, DRAGGING };
bool IsCaptured() const { return m_dragState == CAPTURED; }

我试着重新构建整个解决方案,但无济于事。我正在运行VS2010调试64位,该程序是一个单线程MFC应用程序。这是怎么回事?

您的输出中没有什么奇怪的。&&具有比||更高的优先级,这就是为什么

if (IsCaptured() &&
    abs(delta.x) >= thresh.x || abs(delta.y) >= thresh.y)

被解释为

if ((IsCaptured() && abs(delta.x) >= thresh.x) || 
    abs(delta.y) >= thresh.y)

。如果满足abs(delta.y) >= thresh.y条件,那么整个if条件的结果根本不依赖于IsCaptured()

编译器并不关心你是否在换行符中"表达"了你的意图。运算符优先级很重要。换行不行。

你显然想要做的是

if (IsCaptured() && 
    (abs(delta.x) >= thresh.x || abs(delta.y) >= thresh.y))

注意||子表达式的操作数周围放置了额外的大括号。

考虑如下:

(IsCaptured() && abs(delta.x) >= thresh.x || abs(delta.y) >= thresh.y)

:

 (false && true) || true

你的IsCaptured()不必对progress为真,因此很可能在两个打印输出中都为假。

您可能应该首先确保两个false不同时指向第一个跟踪行。

如果第二个跟踪行实际上在这里打印false,那么您可能正在处理一个典型的竞争条件,并且需要防止它。