The C/C++ preprocessor recognizes commas as macro argument separators unless they are nested inside parentheses. Just parentheses. Brackets, braces and template markers don't count:
The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. (C++14 §16.3/11; C11 §6.10.3/11)
(A side effect of the above is that you can use unbalanced braces and brackets as macro arguments. That's usually not a very good idea, but you can do it if you have to.)
Problems occasionally crop up as a result; a common one is unwanted multiple arguments when the argument is supposed to be a block of code:
MY_FANCY_MACRO(1000, { int i=0, j=42; ... })
Here, the macro is called with (at least) 3 arguments, although it was probably written to accept 2.
With modern C++ (and C) compilers, you have a few options. In a fairly subjective order:
Rewrite the macro as an inline function. If the argument is a code block, consider using a templated function which could accept a lambda or other functor. If the argument is a type, make it a template argument instead.
If surrounding the argument with redundant parentheses is syntactically valid, do that. But in such a case it is almost certainly the case that suggestion (1) above would have worked.
Define:
#define COMMA ,
and use it where necessary:
FOO(baz<20 COMMA 30>);
This doesn't require modifying the macro definition in any way, but it will fail if the macro passes the argument to another macro. (The replacement will be done before the inner macro call is parsed, so the multiple argument problem will just be deferred to the inner call.)
If you expect that one macro argument might contain unprotected commas, and it is the last or only argument, and you're in a position to modify the macro, and you're using C++11/C99 or better (or gcc, which has allowed this as an extension for some time), make the macro variadic:
#define FOO(...) printf("%d\n",__VA_ARGS__::val())