In my opinion, this is preprocessor abuse even if it worked. The only thing I can think of is that for some reason it is turning the comma from an argument separator into a comma operator.
Did you have some extra parentheses that you aren't showing?
A truly elegant approach would be extending digitalWrite() to accept higher pin numbers. In that, it maintains interface compatibility with the other pins, and anyone who has ever programmed an Arduino would instantly understand it.
jecottrell:
Kind of obviously, any literal 'p' that is seen in bitOn, will be substituted in bitSet during compilation, no?
Correct. The whole thing works because the preprocessor applies macros iteratively / recursively. You may be able to deduce when the iteration / recursion is applied by the fact that your original attempt did not work.
If your macro is complicated, you may want a more descriptive name for the variable argument than VA_ARGS. CPP permits this, as an extension. You may write an argument name immediately before the ‘...’; that name is used for the variable argument.
This #define BITSET(...) bitSet(VA_ARGS)
Could be this: #define BITSET(args...) bitSet(args)