2010-05-15 98 views
6

我最近在C語言中啓動了一個小型個人項目(RGB值到BGR值轉換程序),我意識到一個從RGB轉換爲BGR的函數不僅可以執行轉換,還可以執行反轉。顯然這意味着我並不需要兩個功能rgb2bgrbgr2rgb。但是,我使用函數指針而不是宏是否重要?例如:預處理器「宏函數」與函數指針 - 最佳實踐?

int rgb2bgr (const int rgb); 

/* 
* Should I do this because it allows the compiler to issue 
* appropriate error messages using the proper function name, 
* not to mention possible debugging benefits? 
*/ 
int (*bgr2rgb) (const int bgr) = rgb2bgr; 

/* 
* Or should I do this since it is merely a convenience 
* and they're really the same function anyway? 
*/ 
#define bgr2rgb(bgr) (rgb2bgr (bgr)) 

我不一定是在尋找執行效率的變化,因爲它更多是出於好奇的主觀問題。我清楚地知道,使用這兩種方法既不會損失也不會獲得類型安全。函數指針只是爲了方便嗎?還是有更多的實際好處可以獲得,但我並不知道?

+9

就我個人而言,我只是想出了一個描述兩種用法的名字,比如'int swap_rb()';) – caf 2010-05-15 00:22:10

+0

@caf:絕對是另一個好主意。它完全避免了這個問題,但它是一個合理的選擇。 +1 – Dustin 2010-05-15 01:54:15

回答

6

另一種可能性是隻讓第二個函數調用第一個函數,讓編譯器擔心優化它(通過內聯或生成尾調用)。

+0

好主意。畢竟,爲什麼我應該嘗試創建比我的優化編譯器更好的代碼?它並沒有真正改變整體行爲,只是基本的機器指令。對於記錄,我沒有真正保存任何字節,通過使用函數指針,宏或子例程在剝離不需要的項目的二進制/可執行文件後調用真正的函數。最後,編譯器只更改了三個字節(是的,只有三個字節),所以就優化而言,我無法做到比現有的任何更好,而無需通過內聯彙編降低我的代碼的便攜性。謝謝! :d – Dustin 2010-05-15 02:43:38

5

我會使用宏。它更常見,更具慣用性,並且跨越翻譯單元遇到更少的問題(即,您不必擔心聲明宏靜態)。

此外,通過使用函數指針,可以防止在大多數編譯器上內聯。

最後,函數指針,有可能爲客戶做到這一點:

int evil(const int bgr) { /* Do something evil */ } 

bgr2rgb = evil 

當然,他們可能不希望這樣,但它可能有可能是一個名爲類似的變量bgr2rgb下來行,其中只需要一個錯字....

宏是安全的,但我會這樣定義它 - 沒有必要爲一個函數宏在這裏:

#define bgr2rgb rgb2bgr 
+1

感謝您提及函數內聯的丟失。這絕對是值得了解的東西!另外,我顯然可以對函數指針進行const限定,防止它被重新賦值給另一個函數。至於使用不是函數式的宏,我沒有看到任何好處,儘管我可以想象一個問題,像'int bgr2rgb = 0;'這樣荒謬的東西是可能的。就安全性而言,類似功能的宏更好,因爲它避免了這樣的問題。畢竟,並不是所有的宏都有這樣奇怪的名字。總體輸入很棒!我希望有更多深思熟慮的答案! – Dustin 2010-05-15 00:20:04

+2

類似函數的宏更好,因爲它意味着您仍然可以擁有一個名爲'bgr2rgb'的結構成員,而不會產生奇怪的結果。 – caf 2010-05-15 00:20:47

+0

@caf:我同意,但是使用類似於函數的宏,不能將函數bgr2rgb分配給函數指針。使用達斯汀的第一種方法更好,因爲它避免了兩個宏觀問題。 – tomlogic 2010-05-15 14:40:50