2016-01-13 37 views
14

考慮一個(只讀第三方)頭lib.h有:如何重命名C預處理器宏?

#define XYZ 42 

在源文件中,我想用這個詞XYZ在毫無關係的目的,並且不希望與42替代。但是,在同一個源文件中,爲了其他目的,我也希望從lib.h訪問值42,而不對其進行硬編碼。我如何將重命名爲將宏從XYZ改爲LIB_XYZ

下不起作用,因爲預處理器要XYZLIB_XYZ被替換的時間,但XYZ已經未定義:

#include "lib.h" 
#define LIB_XYZ XYZ 
#undef XYZ 

有沒有辦法欺騙預處理器爲擴大LIB_XYZ到它的最終XYZ之前的值是否丟失?

+2

如果你想從第三方頭文件中獲得LIB_XYZ的定義,並且不想使用除C編譯器以外的任何東西,我認爲你被卡住了。如果我必須這樣做,我可能會編寫一個腳本來將lib.h轉換爲our_lib.h,並選擇#define進行修改,使我的代碼包含our_lib.h,並使用makefile來使正確的事情發生,如果lib .h改變了。 –

+1

也許[這](http://stackoverflow.com/questions/1793800/can-i-redefine-a-c-macro-then-define-it-back)可以幫助。 –

回答

6

不與預處理器,至少不是我所知道的。

但是,對於您的示例中已知類型的簡單常量,有一種解決方法。

#include <stdio.h> 

// <xyz.h> 

#define XYZ 42 

// </xyz.h> 

enum xyz_constants 
{ 
    LIB_XYZ = XYZ, 
}; 

#undef XYZ 

#define XYZ 27 

int 
main() 
{ 
    printf("old value: %d, new value: %d\n", LIB_XYZ, XYZ); 
    return 0; 
} 

未示出從stdio.h絨毛,這個代碼是預處理以以下內容。

enum xyz_constants 
{ 
    LIB_XYZ = 42, 
}; 

int 
main() 
{ 
    printf("old value: %d, new value: %d\n", LIB_XYZ, 27); 
    return 0; 
} 

您可以擴展此在一定程度上爲其他數據類型和某些函數宏,但當然有限制。

無論如何,爲什麼你需要特定的標識符XYZ?你不能爲你的宏使用一個不同的名字嗎?

+1

enum技巧非常棒!謝謝! Re why:XYZ是另一個我通過串聯構建的第三方宏的子串,並且連接宏是通用的(適用於XYZ或ABC或其他),所以堅持使用XYZ。 – alexei

+0

這個解決方案只是救了我:) – MByD

0

使用另一個.c文件,並將宏值分配給全局變量。

4

如果XYZlib.h [或各種常數],則可以使用一個enum

enum { LIB_XYZ = XYZ }; 
#undef XYZ 

如果XYZ以上,則必須創建(例如)myxyz.c不是包括lib.h並使用XYZ那裏(其他文件可能包括xyz.h

不同的是,#define LIB_XYZ XYZ可以在該行得到解決,只有當你以後使用它,如:

foo(LIB_XYZ); 

這樣就不會工作,因爲你已經#undef'edXYZ

0

預處理器符號的名稱。沒有預處理指令可以在保留內容的同時更改名稱本身。例如,給定任一:

#define FOO 42 

#define FOO(x, y) x ## y (

沒有方法來定義一個宏稱爲BAR其具有相同的內容,而無需重複這些定義。也就是說,不存在像無操作:

#alias BAR FOO // nonexistent fantasy macro-cloning preprocessor directive 

也不是這樣的:

#rename BAR FOO // like #alias BAR FOO followed by #undef FOO 

如果我們這樣做:

#define BAR FOO // for the #define FOO 42 case 

它不是一個別名。宏BAR被定義爲使得其替換標記序列是標記FOO而不是42。如果FOO宏消失,則BAR失去其含義。

還要注意的是C預處理宏不能擴展到預處理指令,所以下面的方法也行不通

// wrong: 
#define MACRO_DEFINER(NAME) \ 
    #define NAME 42 

MACRO_DEFINER(FOO) // hoping for #define FOO 42: no such luck 
MACRO_DEFINER(BAR) // hoping for #define BAR 42: likewise 

恐怕你得走幾步回頭找一個您想要解決的任何問題的替代策略。如果您遇到問題,請創建一個關於實際問題的新問題。

始終存在代碼生成:在構建時生成C或C++。那麼,如果你只是調整你的發電系統,那麼你可以想象的任何文本替代或擴展都是可能的。