8

I'm trying to do (what I would have thought) was a simple macro expansion

#define CLEAR_DIGIT(a,b)    iconMap[a] &= ~(b)
#define R1 4, 16
CLEAR_DIGIT(R1);

Now I would expect that to expand to CLEAR_DIGIT(4,16) which expands to iconMap[4] &= ~16 However, it doesn't... If I make CLEAR_DIGIT a function:

void ClearDigit(unsigned char a, unsigned char b)
{
    iconMap[a] &= ~b;
}
#define R1 4, 16
ClearDigit(R1);

then it works fine, so R1 being expanded out to the two arguments isn't an issue... Is there any way of forcing it to expand R1 before doing the macro function expansion?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Mike Hudgell
  • 307
  • 1
  • 3
  • 13
  • 1
    Related: http://stackoverflow.com/questions/3776750/macros-evaluation-in-c-programming-language – MByD Dec 21 '11 at 10:09

1 Answers1

11

You could use a helper macro. See also double-stringize problem

#define CLEAR_DIGIT_HELPER(a,b) iconMap[a] &= ~(b)
#define CLEAR_DIGIT(x) CLEAR_DIGIT_HELPER(x)
#define R1 4, 16
CLEAR_DIGIT(R1);
Community
  • 1
  • 1
Benoit
  • 76,634
  • 23
  • 210
  • 236
  • 1
    It's a fine answer, but it does not explain *why* this works. The linked double-stringize problem is notably different - there are special rules when `#` and `##` are used. Those rules do not apply here. – jwd Feb 13 '15 at 21:44
  • This solution did not work for me in visual studio; `R1` is expanded, yet still treated as a single argument. In this case, `CLEAR_DIGIT(R1)` would expand to `iconMap[4, 16] &= ~()`, outputting a warning for not enough arguments. This seems to be related to the problem in [this post](https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly/5134656#5134656). The solution there fixes this problem too. – Hugo Burd Mar 31 '19 at 00:27