2013-11-22 107 views
2

我正在將項目遷移到新的工具鏈,並且函數名稱衝突來自函數,這些函數都位於我的代碼中,並且包含在新的工具鏈中。我的代碼現在必須在舊的和新的工具鏈中編譯,所以我不能破解。如何在包含後刪除聲明

例如在同一個包含內,新的工具鏈已經實現了一個qsort函數(和標準庫的一部分...所以我不能忽略它),但我有我自己的並希望保留一個我可以控制。

有沒有辦法刪除聲明(un-declare?)符號以便使用我的項目的本地代碼?

我搜索了一段時間,還沒有找到任何策略來解決這個問題。

回答

1

C標準沒有提供任何方法來刪除聲明,我還沒有聽說過任何擴展。您的選項包括:

  • 重命名源代碼中與標準庫標識符衝突的標識符。這就是你應該做的。
  • 使用#define#undef之前和之後包括任何標準頭文件以將衝突的名稱更改爲其他內容。下面是一個例子。這違反了有關保留標識符的標準C規則,並可能導致問題,具體取決於您使用的C實現。
  • 使用#define來更改標識符名稱。這在技術上也違反了標準C規則,但不可能導致C實現出現問題。這需要在每個使用標識符的源文件中完成。示例如下。這裏的想法是每個使用自己的qsort標識符(或其他衝突標識符)在預處理器中被另一個不衝突的標識符替換的實例。
  • 您可以修改C實現中的頭文件。這幾乎總是一個壞主意。我提到它只是爲了包含所有可能性。 (另一種可能性,我不包括,因爲它是一個更糟糕的想法,就是你可以修改C實現提供了新的擴展,消除聲明的源代碼。)

這裏的一個例子第二項:

#define qsort StandardLibraryQsortRenamedDueToConflict 
#include <stdlib.h> 
#undef qsort 

這裏是第三項的例子:

#include <stdlib.h> 
#define qsort MyQsort 
#include "MyHeader.h" 

如果你有你自己的頭文件之一後,標準的頭文件,你不能對它們重新排序,則必須使用#undef,以避免與標準頭文件的干擾:

#define qsort MyQsort 
#include "MyHeader0.h" 
#undef qsort 
#include <stdlib.h> 
#define qsort MyQsort 
#include "MyHeader1.h" 

如果沒有一個標準的頭文件後,在任意源文件中的任何您的麻煩頭文件中包含的話,而不是插入上述每一個源文件,你可以只需將每個#define放置在其相應的頭文件中即可。所以MyHeader.h可能看起來像:

… // Various code. 
#define qsort MyQsort 
void qsort(parameter…) 
0

這是一個相當常見的問題,不幸的是它依賴於庫代碼的作者使用唯一的名稱。 win32 windows API頭文件在這方面出了名。

沒有辦法'undeclare'符號,但如果你使用的是C++,那麼你總是可以把你的代碼放在一個命名空間中以避免衝突。

另一個選項當然是簡單地重命名你的函數或者將它添加到DLL/SO中,並用一個不同的名字公開一個可見的函數。

+0

對不起,我只是剛開始使用堆棧溢出,看不到在哪裏指定的語言。 –

+0

沒問題。首先,標籤很容易錯過。 –

2

正常情況下,工具鏈不應該是的問題。編譯器不應該爲你自動包含任何東西,所以包含的內容取決於你。如果發生這種情況,則依賴於:您的#include x.h,而新的工具鏈提供的x.h也包括y.h,而舊的工具鏈沒有。

一個解決方案是修復你的代碼:你真的不應該將名爲qsort的函數與標準庫函數衝突。有沒有什麼能夠阻止你將其重命名爲my_qsort?另一個原因是這是一個「好主意」,因爲如果你的實現和stdlib之間有任何區別,你可能會遇到問題:小問題是開發者對不同行爲的混淆;主要問題是對錯誤版本鏈接使用原型時不同的簽名(即崩潰!)

另一種解決方案是使用身邊那些只需要一個工具鏈頭#ifdef S,但是這可能不是在x.h工作包括y.h的情況。