Unfortunately there are always tradeoffs using macros for something like that, you either end up evaluating the parameters more than once or you have to introduce variables in the macro that may shadow existing variables. Some compilers have extensions to help with that: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
You certainly don’t have to introduce the risk of shadowing existing variables. You just use the standard
#define MACRO(x) \
do { \
/* Define whatever variables you like */ \
/* Do things... */ \
} while (0)Second, you still risk shadowing existing variables, even if you make an effort to use "unlikely" names for the locals such as "___my_macro_secret_variable_1", if the macro might be used in one of its own arguments. For example MACRO(MACRO(x)).
If that sounds unlikely, consider MAX(a,MAX(b,c)), which is likely to happen eventually, if your codebase uses such macros or if they are part of a library.
#define maxint(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b; })
>Note that introducing variable declarations (as we do in maxint) can cause variable shadowing [...] this example using maxint will not [produce correct results]: int _a = 1, _b = 2, c;
c = maxint (_a, _b);