1

我必須維護具有通用組件和產品特定組件的C代碼。我想簡化我的代碼,這樣我只有一個通用product.h文件,其中有像C預處理器計算特定產品包括

#if (PRODUCT_ID == 1) 
    #define PRODUCT_NAME Product1 
#else 
    #if (PRODUCT_ID == 2) 
     #define PRODUCT_NAME Product2 
    #else 
     #error "Unsupported product id" 
    #endif 
#endif 

的結構之後,每當我有一個頭foo.h中其中有產品的具體成分,我想用的語法像這樣

#include "product.h" 
#include PRODUCT_SPECIFIC_INCLUDE 

其中PRODUCT_SPECIFIC_INCLUDE應從__FILE__導出和PRODUCT_NAME宏這樣一種方式,它會轉化爲

#include "Product1/foo.h" 

也就是說,產品特定的頭文件與通用文件具有相同的文件名,但位於產品特定的文件夾中,其名稱爲值爲PRODUCT_NAME的宏。

看來,無論我嘗試有預處理器字符串化問題。我不能成爲第一個想要這樣的結構的人。我錯過了什麼?

更新

這是我目前有PRODUCT_SPECIFIC_INCLUDE不工作

#define TOKENPASTE(x, y) x ## y 
#define TOKENPASTE2(x, y) TOKENPASTE(x, y) 
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__) 
+0

我不確定有可能使用標準的C預處理器。相反,您可能必須在構建環境中執行此操作。 –

+0

請顯示與'PRODUCT_SPECIFIC_INCLUDE'相關的宏 –

+0

這是我目前對'PRODUCT_SPECIFIC_INCLUDE'不起作用的宏,它不起作用#define TOKENPASTE(x, y) x ## y #define TOKENPASTE2(x, y) TOKENPASTE(x, y) #define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE_\_)

回答

2

你可以做這樣的事情

#define STR2(F) #F 
#define STR(F) STR2(F) 
#define MAKE_PRODUCT_INCLUDE(FILE) STR(PRODUCT_SPECIFIC/FILE) 

#include MAKE_PRODUCT_INCLUDE(foo.h) 

,但我不知道的方式,以避免重複的文件名。使用__FILE__給出了一個字符串,我不知道在預處理器中連接字符串(並置字符串連接的事實是一個解析器功能,而##不適用於那個「foo」「bar」不是拼寫一個有效的令牌)。

0

第一個代碼可以簡化爲:

#if (PRODUCT_ID == 1) 
    #define PRODUCT_NAME Product1 
#elif (PRODUCT_ID == 2) 
    #define PRODUCT_NAME Product2 
#else 
    #error "Unsupported product id" 
#endif 

其次,你想獲取所需的包含標題名稱,但問題出現在以下兩行中:

#define TOKENPASTE(x, y) x ## y 
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__) 

__FILE__此宏擴展到電流輸入文件的名稱, 在C字符串常量形式

TOKENPASTE(PRODUCT_SPECIFIC, __FILE__)| - >product ## "foo.h"

product and "永遠不會給出有效的標記。這就是CPP給你錯誤的原因。你需要的是將文件名作爲純文本,這樣你就可以將它與其他宏組合起來。

你可以這樣說:

#define TOKENPASTE(x) #x 
#define TOKENPASTE2(x) TOKENPASTE(x) 
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC/foo.h) 
#include PRODUCT_SPECIFIC_INCLUDE