2014-03-04 93 views
1

我正在編寫一個stm32f4芯片上的C++應用程序,該芯片有幾個要控制的IO。我的一位同事建議爲所有這些IO製作預處理語句,以使代碼更具可讀性。在預處理器語句中使用C函數

例如:

#define FAN_ON  GPIO_SetBits(GPIOD, GPIO_Pin_0); 
#define FAN_OFF GPIO_ResetBits(GPIOD, GPIO_Pin_0); 

這是確定這種方式,如果沒有,爲什麼? 我還沒有太多的微控制器經驗,但我讀過分號不應該用在預處理器語句中,我也不確定在預編譯器語句中使用函數是否是一種很好的風格?

謝謝你的幫助!

+1

這不是微控制器編程,而是基本的'C'。請查看[C#中的#define指令](http://msdn.microsoft.com/en-us/library/teas0593.aspx) –

+0

IMO,這樣做的缺點是它使得遠遠少於可讀的代碼。 – DiBosco

回答

5

理論上很好,但你應該避免使用分號。

這是最好的包裹代碼放在一個虛擬的循環:

#define FAN_ON do { GPIO_SetBits(GPIOD, GPIO_Pin_0); } while(false) 

這使得宏的行爲就像一個單獨的語句。

+0

現在宏也不會打破你最喜歡的迭代器的縮進! – pmr

1

要回答你的第一個問題,儘管這很常見,但使用預處理器語句定義函數是非常糟糕的風格,除非你真的需要預處理器。如果需要諸如__LINE__之類的東西,或者預處理器替換技巧(如將函數名稱放在char *變量中),則確實需要預處理器。你可以定義一個函數void fan_on(void)void fan_off(void)而不是這些宏,如果你想在頭文件中聲明它們,你甚至可以聲明它們爲static inline,就像使用宏一樣。調試器可以比宏更好地使用函數,並且可以更好地進行調試。

正如你所說,如果你仍然想使用宏,你不應該使用分號,並使用do while(0)結構,如果你不使用宏,如果單線if塊將只執行宏的第一行。

+0

謝謝,我想我會用內聯函數來完成它。我不確定的唯一事情是靜態的。如果函數是類方法而不是明確表示它們必須是靜態的,但是如果'fan_off'是一個簡單的C函數,我想我只需要聲明它是'內聯'的,而不是'靜態內聯'? – user3379420

+0

在此上下文中,static與extern相反,並且與C++類無關,這意味着該函數具有內部鏈接(即它只在包含它的c文件中可見)。如果你沒有聲明靜態函數,那麼你將使用具有外部鏈接功能的函數(在整個程序中可見)將函數的定義與c文件一樣多,並且鏈接器會抱怨多個定義。 –