2015-08-14 44 views
1

我怎樣才能在編譯時測試宏參數的字符串值中Ç參數在C預檢查

我正在爲微控制器編寫包裝宏,其格式爲C(GNU)。

我有一些宏,像這樣工作:

#define _ReadBits(port, mask)  (PORT ## port) & (mask) 
#define ReadBits(portmask)   _ReadBits(portmask) 
#define SWITCH D, (1<<7) 

這樣我可以說:

foo = ReadBits(SWITCH); 

,我會得到

foo = PORTD & (1<<7); 

那偉大工程。我想擴大這些做這樣的事情:

#define _ConfigAnalog(port, mask) BUILD_BUG_ON(port != B); AD1PCFGCLR = (mask) 
#define ConfigAnalog(portmask) _ConfigAnalog(portmask) 

也就是說,我希望發生編譯時錯誤,如果參數portB(因爲這個微控制器可以配置只有端口B作爲模擬)。

是否有某種方式在Ç做到這一點?

回答

2

想通了自己:

#define PORT_B_SUPPORTS_ANALOG 

#define __CheckPort(p) PORT_##p##_SUPPORTS_ANALOG 
#define __ConfigAnalogBits(mask) AD1PCFGCLR = (mask) 

#define _ConfigAnalogBits(port, mask) __CheckPort(port); __ConfigAnalogBits(mask) 
#define ConfigAnalogBits(portmask)  _ConfigAnalogBits(portmask) 

#define NO_GOOD C, (1<<3) 
#define VOLTAGE B, (1<<3) 

void tryit(void) 
{ 
    ConfigAnalogBits(VOLTAGE); 
    //ConfigAnalogBits(NO_GOOD); 
} 

如果 「端口」 是B,則_CheckPort編譯成空語句。

如果「端口」是別的,生成錯誤發生。

+3

避免使用以下劃線接着是其他下劃線或大寫字母開頭的標識符(例如,避免'__this'和'_This'),因爲這樣的標識符被保留用於執行。 – dreamlax

+0

@dreamlax:謝謝;將修復。 –

+0

這樣做不會**測試宏參數的任何「字符串值」。它測試一個標識符名稱。如果我的回答中的低估是屬於你的,我認爲重新考慮你的問題(我引用的問題)可能沒有儘可能清楚地說明是公平的。 – Jens

0

我怎樣才能在編譯測試在C宏參數的字符串值?

你不行。

根據C99 6.10.1 條件包含,處理器先決條件必須是一個整數常量表達式,並且可以測試一個宏是否被定義(使用#if#ifdef identifier#if defined(identifier))。

+0

我認爲C預處理圖靈完整。所以你總是可以;問題在於如何。 –

+0

@ nerdfever.com圖靈完備性與任意輸入數據操作無關。一種語言可以是圖靈在月光下完成的。這並不意味着它可以做出關於字符串的決定。 – Gene

+0

@Gene:如果你可以在moonbeams中編碼字符串,那麼我認爲你可以做出關於字符串的決定。 (原則無論如何,不​​是說這是實用的。) –