2012-03-15 67 views
4

我不能弄清楚什麼是使用Ç - 參數宏

#define CRANDOM() (random()/2.33); 

,而不是

float CRANDOM() { 
    return random()/2.33; 
} 
+1

宏給你一個'雙'。如果你有一個非常糟糕的編譯器,它會少用一個函數調用。 – 2012-03-15 12:15:19

+4

我不會把';'放在宏裏面...... – 2012-03-15 12:15:20

+0

@OliCharlesworth;爲什麼宏是不好的做法的另一個原因;因爲C程序員傾向於在他們寫的每一行的末尾寫一個分號; – Lundin 2012-03-15 12:19:52

回答

5

通過使用#define macro你迫使宏的主體被插入inline

當使用函數時,將會有一個函數調用(並因此跳轉到函數的地址(除其他之外)),這會在某種程度上降低性能。

即使每次使用#defined宏時可執行文件的大小都會增加,前者通常會更快。



編譯器可能是足夠聰明的優化掉的函數調用,內聯函數 - 有效使它一樣使用宏。但爲了簡單起見,我們將在這篇文章中忽略這一點。

3

它可以確保到CRANDOM呼叫內聯的優勢,即使編譯器沒有按不支持內聯。

+0

這比過去要重要得多,在編譯器的這些日子裏,可以超過大多數彙編程序員的優化:-)但這可能仍然是正確的答案。 – paxdiablo 2012-03-15 12:18:20

0

調用一個函數會涉及一點開銷 - 在這種情況下,將返回地址推送到機器堆棧和分支。通過使用宏,可以避免這種開銷。很久以前,這很重要。無論如何,現在許多編譯器都會插入這種內聯函數的小函數體。一般來說,試圖欺騙編譯器發佈更快的代碼是愚蠢的遊戲;你通常最終會創造出更慢的東​​西。

3

首先,這#define是不正確由於在最後的分號,編譯器將在卻步:

float f = CRANDOM() * 2; 

其次,我個人儘量避免使用預處理超越分離獨立於平臺的部分在跨平臺的代碼中,當然代碼專門用於DEBUG或非DEBUG構建。

nightcracker正確地指出它永遠是「有效的」內聯,但鑑於你可以重新編寫函數是inline本身,我看不出有什麼優勢,使用預處理器版本除非的C編譯器的問題不一致。

1

前者是舊式。前者的唯一優點是如果你有一個遵循舊C90標準的編譯器,這個宏將作爲內聯工作。在現代C編譯器中,您應該始終寫入:

inline float CRANDOM() { 
    return random()/2.33f; 
} 

其中inline關鍵字是可選的。


(注意,浮動文字必須在年底有AF,否則你力的計算將雙執行,然後您可以隱式輪入浮動。)

+0

無論如何,大多數FPU都以雙精度進行所有浮點計算,除非FPU明確設置爲單精度模式。 – orlp 2012-03-15 12:22:29

+0

@nightcracker如果甚至有FPU可用,那就是。 OP沒有提到任何特定的平臺。 – Lundin 2012-03-15 12:27:30

+0

@Lundin另一個說明是關鍵字'inline'可以被編譯器忽略,它只是告訴它「我希望你內聯這個」的方式,但它可以有效地做任何想要的事情。 – 2012-03-15 12:33:48