2013-12-07 46 views
3

我有下面的宏打印出整数数组的内容用于调试目的:在C宏模拟范围

#define PRINT_ARRAY(ary, num)  \ 
    int ai = 0;      \ 
    printf("{");      \ 
    for(ai=0; ai < num; ++ai) {  \ 
     printf("%d", ary[ai]);  \ 
     if(ai < num-1) printf(", "); \ 
    }        \ 
    printf("}\n"); 

我遇到的问题是,当我使用它不止一次,有些更编译器抱怨我正在重新定义ai

有没有一种方法,使对宏的每次调用标识不同?我可以想出一个名称冲突变化非常小的命名方案,但我想使其自动化。

我知道我可以使用一个函数,但我仍然好奇,因为我想知道是否有一种方法可以用宏来实现。

回答

2

你可以把它放在它自己的范围内。与{}

这一样围绕着它:

#define PRINT_ARRAY(ary, num)  \ 
{        \ 
    int ai = 0;      \ 
    printf("{");      \ 
    for(ai=0; ai < (num); ++ai) {  \ 
     printf("%d", ary[ai]);  \ 
     if(ai < (num)-1) printf(", "); \ 
    }        \ 
    printf("}\n");     \ 
} 

我还加括号围绕num参数,所以你可以使用一个复杂的表达式,而不必奇怪sideffects。

WRT到您的标识符命名:

您可以使用宏扩展使用参数更改名称,但在目前还没有在所有的C预处理器,我知道专柜或循环结构,我不认为这是可能的在每个用户之后自动更改标识符。另一种方法是让宏每次重新定义自己,但afaik也是不可能的。

编辑:

正如已经指出的(感谢阿龙McDaid,也看到他posteed链接:https://stackoverflow.com/a/1067238/146041),你应该使用在你的代码do {} while(0)结构,使您的宏将成为:

#define PRINT_ARRAY(ary, num)  \ 
do {        \ 
    int ai = 0;      \ 
    printf("{");      \ 
    for(ai=0; ai < (num); ++ai) {  \ 
     printf("%d", ary[ai]);  \ 
     if(ai < (num)-1) printf(", "); \ 
    }        \ 
    printf("}\n");     \ 
} while(0) 
+0

'做{...}而(0)'应该多语句宏中使用,请参阅http://stackoverflow.com/a/1067238/146041 –

+0

你应该总是用做..(0)使用宏时。 – this

2

如果您的C符合C99,请在for循环的标头中放入ai的声明。你也应该围绕代码do/while(0)

#define PRINT_ARRAY(ary, num)  \ 
    do {printf("{");      \ 
    for(int ai=0; ai < num; ++ai) {  \ 
     printf("%d", ary[ai]);  \ 
     if(ai < num-1) printf(", "); \ 
    }        \ 
    printf("}\n"); } while(0) 

,以便它可以控制结构后使用,无需用大括号包围它。

+0

删除尾部的';'! –

+0

无论哪种情况,它都应该放在'do {...} while(0)'内。例如,第一个宏在if(...)后立即不正确。 –

+0

@AaronMcDaid修复。 – dasblinkenlight

6

为什么你不使用经典的动态技巧?例如:

#define FOO(EXPR) \ 
    do { \ 
    (EXPR); \ 
    } while(0) 
+1

有关为什么'do {...} while(0)'应该总是与多语句宏一起使用的更多信息,请参阅http://stackoverflow.com/a/1067238/146041 –