typedef重復定義 和 error: ‘long long long’ is too long for GCC


今天發現一個很有意思的編譯問題,然后在Stack Overflow上也有看到類似的。就是出現了 long long long 類型錯誤提示

錯誤提示如下:

/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。

``` #define INT64 long long ```

然后看代碼出錯的地方,就是一個宏定義,怎么會出現問題呢? 然后仔細看了一下代碼發現是鏈接外部庫導致的,工程 A 鏈接了 B_lib.so 和 C_lib.so 兩個動態庫, 然后 B 中用宏定義了 long long , C 中使用typedef重新命名了 long long,順序剛好是宏定義在前,等價於下面兩句代碼:

``` #define INT64 long long

typedef long long INT64;


<p style="font-size: 15px; text-indent:2em; letter-spacing:1px; font-family: '微軟雅黑';">因為宏定義只是簡單的替換,因此導致typedef變成了:</p>

typedef long long long long long;

<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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM