2009年11月3日 星期二

C macro的誤用


macro主要是拿來取代,比如#define MAX_NUM 10,當用到MAX_NUM時,就會被轉成10,我們常用拿macro來define一些函數,比如:
#include <stdio.h>
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))

int main(int argc, char *argv[])
{
    int x=10, y=11, big;
    big = MAX(++x, ++y);
    printf("the bigger + 1 = %d\n", big);

    return 0;
}

可是這裡就會發生問題了,當你使用CPP你可以看到,X全部被++x取代,而Y全部被++y取代,所以執行完的結果顯然就會錯誤了。
int main(int argc, char *argv[])
{
    int x=10, y=11, big;
    big = ((++x) > (++y) ? (++x) : (++y));
    printf("the bigger + 1 = %d\n", big);

    return 0;
}
結果是13而不是12。

這邊應該改寫為
#include <stdio.h>
#define MAX(x, y) \
({ typeof(x) _x = (x); \
    typeof(y) _y = (y); \
 _x > _y ? _x : _y; })

int main(int argc, char *argv[])
{
    int x=10, y=11, big;
    big = MAX(++x, ++y);
    printf("the bigger + 1 = %d\n", big);

    return 0;
}
因為你無法預期使用者會輸入何種表示法,為了避免side effect,還是在內部宣告一個變數儲存使用者的輸入吧。
至於typeof可以參考一下GCC的說明http://gcc.gnu.org/onlinedocs/gcc/Typeof.html。



沒有留言:

張貼留言

熱門文章