1. 程式人生 > >原來我錯怪VC60和WIN8了

原來我錯怪VC60和WIN8了

自己寫的一個用XP+VC60開發的簡單的程式,無論怎麼編譯選項怎麼搞,在XP和WIN7都很好執行。 可是RELEASE版本在WIN8一執行就崩潰,通過log列印,發現是OnInitDialog()函式一執行完程式就崩潰,難道是程式的堆疊亂了,可是為什麼XP和WIN7中執行又好好的? 如果編譯時禁用優化那麼在WIN8也很好地執行,可是又很難找出到底是怎麼被優化錯了? 經過幾天排除,發現把OnInitDialog()中的這兩行程式碼 CHyperLink *pLinkHome; pLinkHome = new CHyperLink(); 放在一個單獨的函式中,再在OnInitDialog()中呼叫,那麼在WIN8中也能很好地運行了。 當然如果直接把這兩行程式碼註釋掉,也可以達到同樣的效果

現在感覺VC60的編譯器優化真不靠譜,所以自己的很多程式存在潛在的危險,真心不爽

焦頭爛額了三天,搞不清是VC6編譯器的問題還是WIN8的問題?

經歷了幾天噩夢,幾乎要放棄了。 有人讓我貼個重建工程,後來我乾脆採用地毯式日誌列印,每執行一行程式碼就做一次列印,終於定位到了問題的所在!!

以前,我喜歡在程式中用 CWnd* pWndPt = GetDlgItem(IDC_STATIC_PT);

的方式記錄一個控制元件的類 以方便用 pWndPt->SetWindowText(str);的方式動態地設定控制元件的標題

原來這種做法是很危險的!! 雖然這種做法在99%以上的情況都是沒問題的,但是危險依然存在,如果這樣做而沒遇到問題,完全是運氣作用。 這種方式我用了十幾年都沒出現問題 這麼多軟體都沒有出現問題,除了其中一個小軟體在WIN8下崩潰了,雖然通過不改變程式邏輯的情況下移動整理程式碼或者禁止編譯器優化,都可以逃過隱患,但是隱患依然存在,說不定在WIN8.2 WIN8.3中又出現崩潰了

而且你想隨便寫一個簡單的程式復現這一現象是很難的,似乎非常地依賴於編譯後的程式碼以及執行的系統。 有時候呼叫有效,有時候是呼叫無效但不崩潰,有時候是崩潰了

MSDN中有: CWnd* GetDlgItem( int nID ) const;

void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;

Return Value

A pointer to the given control or child window. If no control with the integer ID given by the nID parameter exists, the value is NULL. 

The returned pointer may be temporary and should not be stored for later use.

GetDlgItem的返回值是臨時的,不應儲存起來作後續之用