Есть способ сделать такие вещи, которые являются стандартными C. Сначала у вас есть основной макрос, который выполняет работу в обоих случаях
#define ASSERT0(X, RET, ...)
/* put your stuff here that only uses X and RET, and ignores the ... */
Как вы можете видеть, он получает три аргумента или более.И вам нужно договориться, что RET
- это просто пустой токен для случая, когда вам это нужно.
Теперь вы можете обернуть вокруг него
#define ASSERT1(...) ASSERT0(__VA_ARGS__)
Это гарантирует, чтозапятые, которые могут быть внутри отдельных аргументов, будут рассматриваться как разделители аргументов для ASSERT0
.
В этом случае макрос уровня пользователя может быть
#define MY_ASSERT(...) ASSERT1(__VA_ARGS__, ,)
. Это гарантирует, что если вы используете его только с однимАргумент ASSERT0
внизу увидит пустой второй аргумент.Если вы вызываете его с двумя аргументами, ASSERT0
просто увидит их.
Также вам следует подумать об обёртывании вашего внутреннего макроса в do { ... } while(0)
.В противном случае вы можете столкнуться с проблемой "зависания else
" и спутать пользователей с другими синтаксическими эффектами.