Reputation: 5167
I have the following macro to print out the contents of an array of integers for debug purposes:
#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");
The problem I am having is that when I use it more than once, some compilers complain that I am redefining ai
.
Is there a way to make the identifier different for each invocation of the macro? I can come up with a naming scheme that would have a very low change of name collisions, but I'd like to make it automatic.
I know I could use a function, but I am still curious, since I would like to know if there is a way to do this with macros.
Upvotes: 3
Views: 90
Reputation: 1258
You can just put it into it's own scope, e.g. surround it with {
and }
Like this:
#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"); \
}
I also added parantheses around the num parameter, so you can use a complex expression without having strange sideffects.
WRT to your identifier naming:
You can use macro expansion to change the name using a parameter, but as there are not counter or loop constructs in all c preprocessors I know, I don't think it's possible to automatically change the identifier after every user. Another way would be to have the macro redefine itself every time, but afaik that's also not possible.
Edit:
As has been pointed out (thanks to Aaron McDaid, also see the link he posteed: https://stackoverflow.com/a/1067238/146041), you should use a do {
} while(0)
construct around your code, so your macro would become:
#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)
Upvotes: 2
Reputation: 726987
If your C is C99-compliant, put ai
's declaration in the for
loop's header. You should also surround the code with 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)
so that it could be used after control structures without surrounding it with curly braces.
Upvotes: 2
Reputation:
Why don't you use a classic do-while trick? For example:
#define FOO(EXPR) \
do { \
(EXPR); \
} while(0)
Upvotes: 6