站內搜尋

2008/8/21

當 Windows.h 碰上 Winsock2.h 等於 Viual C++ 8.0 爆炸!

你能想像嗎,include 系統 header 居然還要分順序.. =.=b 嚇死我了
果然賣個沙發只能賣個沙發....

這種奇怪的 Bug 居然會出現在還能在他們的 compiler 裡找到....
這星期在 Coding 的時後,很開心的把物件架構規劃好,也很開始的將每隻物件獨立的寫的差不多了,而也都經過 Compiler ,確定一切準備無誤,開始寫 OOP 最開心的一件事,寫最後一個使用物件。
為什麼開心呢?因為假設架構設計的夠清楚,其實使用物件裡的東西會非常非常的精簡,整個看起來會開清爽,而寫 OOP 大概只有這時後會清爽吧(冏..)。
但是,當我將我的所有 header include 完,也把使用的 Coding 完成了,很開心的按下 Compiler .... 居然...
ERROR !!!
而且是一次給本少爺跳了六十幾個... =.=b
....我~~好~~慌~~啊...
不過,再怎麼慌,也只能硬著頭皮看了,仔細觀察這些 error message ,發現大多長的像下面這樣:
\program files\microsoft visual studio 8\vc\platformsdk\include\winsock2.h(112) : error C2011: ‘fd_set’ : ’struct’ type redefinition   
\program files\microsoft visual studio 8\vc\platformsdk\include\winsock.h(54) : see declaration of ‘fd_set’

腦中馬上浮現一頭霧水....我什麼時後 include 了 winsock 了?
經過一整個下午無聊的測試加尋找,最後才終於發現了這個鳥 Bug 的來龍去脈..
原來,在賣個沙發的設計中,winsock.h 跟 winsock2.h 是不能並存的,但是賣個沙發又很搞笑的在最常被使用到的 windows.h 中,很天真的把 winsock.h 給 include 進去了,於事,便造成了一個很搞笑的結果:
  • 一定要在 include windows.h 之前 include winsock2.h
誰能告訴我這是什麼鬼嗎....這個鳥 bug 在小程式還簡好解,假設是一個大的 project ,有數十個人在 work,當其中有某位仁兄寫了一隻 object (註1),而它的 header 明確宣告了它使用了 winsock2.h ( include <winsock2.h> ),而另一名仁兄則使用了 windows.h,經過數個人的繼承、使用,今天終於到了你的手上,而你又很直覺的把二個 hearder 檔都 include 進你的 header,那....
恭喜你,你有 50% 的機率會 Compiler Success。
有沒有一種可笑的感覺.. =.=b ..對,就是這麼可笑..
當然,你也可以很鄉愿就只要碰到時再想辨法調一下順序把它解掉就好,不過其實也有方法解決它。
因為 windows.h 是賣個沙發常用的系統表頭,直接把 include winsock.h 拿掉,可能會對整個系統造成不可預期的影響(比如MFC突然不動了...嚇死你...)。所以,我們可以小小的修改 windows.h,找出 include winsock.h 的部份,在外面包一層 #ifdef __MY_SOCK2_DEF_FLAG__ 。
此後,只要你發現你的程式有運用到 winsock2.h 的部份,便可以在 pre-process 時利用這個 word,來告訴 windows.h 不要將 winsock.h 引入。
雖然這個解決方式可能還是不盡理想,不過應該可以在某種程度上讓這個問題比較不那麼麻煩,在這裡提供給個位參考..
註1:我個人習慣讓一個 file 中盡可能只存在一個 class,如此我方便將它打包成 object 來處理。

熱門文章