一晃眼,原來又有好幾個月沒有上來。其間寫了幾個月的javascript,寫了幾個月的JSP,C++的東西都沒有怎么碰過了。
這幾天要原來項目的C++代碼從32bit的平臺移植到64bit的平臺。由于以前編寫類庫的時候已經(jīng)十分小心,也早有預(yù)謀,所以竟然很順利的全部編譯通過,而且-Wall下面都沒有任何warning。滿心歡喜之下運行了程序。誰知道馬上就是一個Segment faul。沮喪之余用gdb跟蹤了半天都不知道什么地方的問題。加上valgrind,也是一頭霧水,竟然是說標準STL的hash_map的問題……最后在一次跟蹤的時候,無意中檢查一個指針的初始化值,發(fā)現(xiàn)不為空,原因應(yīng)該就在這里。
翻查代碼的上下文,原來指針是跟一個int放在同一個union當(dāng)中,而union的初始化只初始化了int,而沒有初始化指針。在64bit機器的gcc下,int是32bit而指針是64bit,所以就導(dǎo)致指針不為空的現(xiàn)象。所以趕緊把代碼中所有union的地方都找出來檢查一遍。幸好union這種東西平時不敢多用,也沒發(fā)現(xiàn)其他的異常。程序重新編譯,再運行,沒有Segment fault了。
然后再運行了一批unit test。發(fā)現(xiàn)其中有幾個不能通過,其原因其實也是比較無聊。都是自己不小心之過:
1、sha1的代碼copy php的,其中一個php_uint32變量竟然自己寫了unigned long,傻瓜致極
2、有個地方保存各種長度整數(shù)到文件,因為偷懶,把函數(shù)寫成了模板,大概就是:
???template<typename typeInt>
??????int write(typeInt n) {
?????????writeToFile( &n, sizeof(n));
??????}
???然后一個不小心,想寫個string的長度的時候就變成了:? write( str.length() );
?? str.length()類型是size_t,64bit,與32bit系統(tǒng)的不一樣,當(dāng)然也就出錯了。
?? 其實平時都已經(jīng)很小心,盡量使用static_cast強制轉(zhuǎn)換為特定長度類型的變量再輸出的了,偏偏就是漏了一兩個地方。