2015-12-18 49 views
1

有沒有更好的方法來做到這一點(在GCC C)?在C預處理器中比較字符串的方法? (GCC)

我想定義一些代表硬件平臺的符號,用於條件編譯。

但我也希望可打印字符串描述硬件(用於診斷)。

理想情況下,我想能夠做到:

#define HARDWARE "REV4C" 

#if (HARDWARE == "REV4C") 
    #define LED_RED  // define pin addresses, blah blah... 
#endif 

printf("HARDWARE %s\n", HARDWARE); 

但我不認爲這是允許的在C.這工作,但它的醜陋:

#define REV4C (403) // symbols for conditional compilation 
#define REV421 (421) 

//#define HARDWARE REV4C // choose hardware platform (just one) 
#define HARDWARE REV421 

#if (HARDWARE == REV421) // define strings for printing 
    #define HARDWARE_ID "REV421" 
#elif (HARDWARE == REV4C) 
    #define HARDWARE_ID "REV4C" 
#else 
    #define HARDWARE_ID "unknown" 
#endif 

#if (HARDWARE == REV421) 
    #define LED_RED  // define pin addresses, blah blah... 
#endif 

/* ... */ 

printf("HARDWARE_ID %s\n", HARDWARE_ID); 

這是醜陋的,因爲它需要兩個單獨的符號,HARDWARE(用於比較的整數)和HARDWARE_ID(用於打印的字符串)。並生成邏輯值HARDWARE_ID

有沒有更好的方法?


編輯:我不認爲這是how to compare string in C conditional preprocessor-directives的重複。

這個問題(和答案)沒有解決如何得到一個可打印的字符串,而沒有結束兩個相似的符號。

(我沒看這個問題的答案張貼了這個問題之前。)

+0

你的第二個建議是沒有那麼糟糕。當然,你不應該爲每個你定義的東西重複'#if'塊,而是一起定義所有的東西。這種方法還可以讓你控制有效值,並允許你在沒有指定硬件時在'#else'子句中發出'#error'。 (在'#if's中,未知宏的值爲零。) –

+0

@JosephQuinsey該問題沒有解決如何獲得可打印的字符串。 –

回答

4

做的通常的方式就是定義所需的配置符號,然後有條件地定義所有其他的:

// Select config here 
#define REV4C 
//#define REV421 

#ifdef REV4C 
    #define HARDWARE_ID "REV4C" 
    #define LED_RED 
#elif defined(REV421) 
    #define HARDWARE_ID "REV421" 
    // ..... 
#else 
//....... 
#endif 
+0

並非我所有的#ifdefs都在同一個地方,因此解決方案退化爲我原來的「醜陋但有效」的解決方案。 –

+0

@ nerdfever.com重新組織你的代碼,讓他們在一個地方 –

+1

@ M.M輕鬆讓你說。代碼已經*組織起來,以便某些其他事物聚集在一起... –

0

要做實際的案例分析,看看標記爲重複的評論。實際上也有像

#define STRINGIFY(...) #__VA_ARGS__ 
#define HARDWARE_STR STRINGIFY(HARDWARE) 
0

值作爲一個字符串,就可以使用字串化的東西完全不同的方法將字符串相關的邏輯移動到構建

C預處理器是相當有限的,但make(與規則中的shell命令一起)是完全靈活的字符串處理器。例如。與GNU make

ifeq ($(CONFIG),REV4C) 
    HARDWARE_ID = \"REV4C\" 
else 
    HARDWARE_ID = \"DEFAULT\" 
endif 
CFLAGS += -DHARDWARE_ID=$(HARDWARE_ID) 

,並呼籲爲

gmake CONFIG=REV4C