在上班時間看到這篇文章,就很想紀錄一下。底下會有link。
主要是看到一篇文章問,為何 #define do { ... } while ( 0 ) 跟inline會交叉互用,本來提問者以為是等同的意思。但以我對inline的初淺了解,inline內的code展開與否的決定權仍然在compiler上。#define則是前處理器要處理的,所以勢必得展開了。
問題來了,為何要用 #define do { ... } while ( 0 ) 這樣的方式去定義一個function呢?回答的前輩有趣得以一個問題當開頭:
假設一個function以#define來看
#define sq(a) (a*a)
int answer = sq(5); // 答案是 25
好像一般簡單的應用沒什麼問題,假設變成以下呢?
int answer = sq(5+1) // 答案不是 36 啊.....
因為基本上前處理器會幫我們展開,但是不會幫我們注意括號,因而變成 5 + 1 * 5 + 1 變成11了。
所以我們得注意#define時候括號的重要性。變成以下就不會產生錯誤的答案:
#define sq(a) ((a)*(a))
但是inline時候就不會發生這類的問題了。
回到此篇的主軸,為何要使用 #define do { ... } while ( 0 ) 去定義我們的函數呢?它是有其特殊意義的。
#define swap(x,y) { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; }
這樣的函數代入以下會如何呢?
if ( x > y )
swap(x,y);
else
otherthing();
展開它。
if ( x > y )
{ int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; };
else
otherthing();
聰明的你,發現問題了嗎?多出了一個分號!
if ( x > y ) {
int tmp_n ;
tmp_n = x
x = y
y = tmp_n;
}
; <---- 這邊多分號,慘了 ~~~~
else
otherthing();
這邊就會產生編譯錯誤了,所以才導入 #define do { ... } while ( 0 )來解決,此段程式碼就會變成:
if ( x > y )
do {
int tmp_n ;
tmp_n = x;
x = y;
y = tmp_n;
} while(0);
else
otherthing();
神奇吧!跟我一樣佩服這位前輩替咱們解惑吧!
出自:http://phorum.study-area.org/index.php?topic=56407.0
Enjoy it.
沒有留言:
張貼留言