今天發現一個頗有意思的編譯問題,而後在Stack Overflow上也有看到相似的。就是出現了 long long long 類型錯誤提示google
錯誤提示以下:spa
/home/yejy/algorithm_and_data_structure/main.cpp:50:17: error: ‘long long long’ is too long for GCC #define INT64 long long ^
顧名思義,一個long佔4個字節,兩個就是8字節,總共64位,等於系統是64位的,若是你使用3個long那就96位了,那確定會有問題,正常狀況下也沒人會定義三個long。code
``` #define INT64 long long ```而後看代碼出錯的地方,就是一個宏定義,怎麼會出現問題呢? 而後仔細看了一下代碼發現是連接外部庫致使的,工程 A 連接了 B_lib.so 和 C_lib.so 兩個動態庫, 而後 B 中用宏定義了 long long , C 中使用typedef從新命名了 long long,順序恰好是宏定義在前,等價於下面兩句代碼:blog
``` #define INT64 long longtypedef long long INT64;接口
<p style="font-size: 15px; text-indent:2em; letter-spacing:1px; font-family: '微軟雅黑';">由於宏定義只是簡單的替換,所以致使typedef變成了:</p>
typedef long long long long long;ci
<p style="font-size: 15px; text-indent:2em; letter-spacing:1px;font-weight: bold; font-family: '微軟雅黑';">這應該屬於比較典型的連接多個外部庫致使的代碼衝突問題,而後本身大概思考了一下,併到google上檢索了相關問題的解決,在這裏總結一下,問題的解決思路主要應該有如下幾種:</p> <p style="font-size: 15px; letter-spacing:1px;font-weight: bold; font-family: '微軟雅黑';">1. <font color="#FF0000">同一個項目使用同一份基礎類型定義頭文件</font></p> <p style="font-size: 15px; text-indent:2em; letter-spacing:1px;font-family: '微軟雅黑';">在同一個項目當中,固然最好確定是全部庫都引用同一個頭文件中的基礎類型typedef定義是最好的,這樣就不會出現沒必要要的衝突,在項目一開始的時候就規定好相關的基礎類型定義的地方。而後由於這邊是外部庫,所以想把全部基礎類型都定義到同一個文件不太現實,所以這種方式對於上述問題並不適用,可是若是不是外部庫的話,這個仍是要注意的。整個工程都用一份,對於不一樣平臺能夠作一下區分。</p> ![](https://img2018.cnblogs.com/blog/1285081/201809/1285081-20180927202250779-1847015286.png) <p style="font-size: 15px; letter-spacing:1px;font-weight: bold; font-family: '微軟雅黑';">2. <font color="#FF0000">將問題有編譯階段推遲到連接階段</font></p> <p style="font-size: 15px; text-indent:2em; letter-spacing:1px; font-family: '微軟雅黑';">因爲大部分錯誤都是redefinition; different basic types,固然我這個比較奇葩,這些錯誤都是發生在編譯階段,那咱們只要保證在編譯的過程當中不衝突就能夠了,也就是讓兩個衝突的typedef不在同一個代碼文件中使用。像我這個問題,include的頭文件的時候,先include包含typedef的文件,而後再include包含宏定義的文件,那編譯也是能夠經過的。而後對於二者徹底衝突,保證不在一個代碼文件中使用就不會有問題(可考慮經過extern來隔離相關接口的定義,就是將<font color="#FF0000">調用發生衝突類型</font>的流程放到其餘文件中處理)。到了連接階段,由於這個時候都是以原始類型爲基準,所以也不會有問題。若是是臨時引用兩個庫出現問題,應該就只能經過這個方式來嘗試了。</p> extern方式可參考該連接:<a href="http://brhwww.blog.163.com/blog/static/61817885201056104455163/" target="_red"><font color=#00ffff size=10>extern 隔離</font></a> <p style="font-size: 15px; letter-spacing:1px;font-weight: bold; font-family: '微軟雅黑';">3. <font color="#FF0000">在C++語言中使用命名空間(namespace)</font></p> <p style="font-size: 15px; text-indent:2em; letter-spacing:1px; font-family: '微軟雅黑';">這個應該是能夠解決問題的,可是須要庫的開發者有這個意識,對本身開發的庫使用命名空間封裝起來,避免與其餘庫或者客戶代碼發生衝突。這個只在C++語言裏面能夠使用(C語言中不存在)。</p> <p style="font-size: 15px;text-indent:60em;letter-spacing:1px; font-family: '微軟雅黑';">2018年9月27日20:52:02</p>