以前一直以為宏的定義挺簡單的,沒有寫過長的宏函數,最常用的是MAX()的定義,今天寫一個宏函數的時候,相對於MAX()來說,稍微有點長,然后踩了一個小坑。
一開始將宏函數定義的時候,為了書寫方便,將一個函數寫成了幾行,但是沒有用連接符號連接起來,類似於下面
1 #define CHECK(ret) ({
2 int ret; 3 ... 4 })
GCC總是提示ret不在范圍內。想了半天沒有明白怎么回事。
然后我發現了一個問題。
我的VIM定義宏函數時,#define那一行是顯示的藍色,但是我的 int ret,以及下面的都是普通的白色,然后我查看了我以前的代碼,發現我的宏定義VIM顯示的都是藍色。
我馬上想到的是我的下面定義的 int ret往下都沒有包括進宏里面,這個宏,定義的是 CHECK(ret) == ({ ; 下面空出來的都是在main函數以外,這個當然會報錯了,然后我用了連接符號,代碼如下
1 #define CHECK(ret) ({ \
2 int ret; 3 })
OK!!!
VIM中代碼全是藍色了,這樣就識別了整個宏了。
細細想一下,宏的定義是怎么結束的,宏的結尾是沒有分號的,那么推斷宏是通過回車來結束的,也就是整個一行都是宏,所以當宏很長時,就要用到連接符來連接了。
這樣這個推斷也由上面的錯誤證明了。
這個坑不大,但是它也從側面說明了,寫程序,是個細心的活兒。這種小問題,以后就不要再犯了吧!
還有一點,連接符后面是不能有空格的,GCC會出現警告:
warning: backslash and newline separated by space
來自IBM網站上的解釋是:
Solution: The backslash (\) character is used as the continuation character to continue #define statements and strings to the next line. GCC expects the backslash character to be the very last character on the line. This warning indicates that there is a space after the backslash. Delete the space and any other characters that come after the backslash.
