[英]Strange program and debugger if statement behavior
這是一個完整性檢查,因為我失去了我的。
我有一個方法IsCaptured()
,它將枚舉狀態成員與給定值進行比較並返回一個bool
。 我結合使用鼠標閾值檢查來確定是否應該發送拖動開始消息並開始拖動操作。 問題是當它不應該被鼠標移動時觸發。 我添加了跟蹤消息,如下所示:
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;
// ...
}
現在奇怪的部分,輸出:
false
false
該方法實現如此,並且m_dragState
設置為NONE
直到攔截了一個按鈕:
enum { NONE, CAPTURED, DRAGGING };
bool IsCaptured() const { return m_dragState == CAPTURED; }
我試過重建整個解決方案無濟於事。 我正在運行VS2010 Debug 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()不一定是真的進步,所以在兩個打印輸出中很可能都是假的。
您應該首先確保兩個false不同時引用第一個跟蹤線。
如果第二條跟蹤線在這里實際打印為假,那么您可能手上有經典的競爭條件,需要防范它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.