The next macro (COUNT_ARGUMENTS) builds upon ELEVENTH_ARGUMENT. The more arguments that are passed to COUNT_ARGUMENTS, the more the »counting arguments« (9, 8, 7…) are pushed to the right. Thus the macro evaluates to the number of arguments that are passed to the macro.
#include "eleventh-argument.h"
// Note: With GCC, the preprocessor eliminates the comma in
// , ## __VA_ARGS__
// IF __VA_ARGS__ is empty. (https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html)
// This is necessary to correctly count the arguments
//
#define COUNT_ARGUMENTS(...) ELEVENTH_ARGUMENT(dummy, ## __VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
debug-variable-arguments.h is a file to be included. It concatenates DEBUG_ with the result of COUNT_ARGUMENTS to produce something like DEBUG_2 which takes a printf-format and two arguments.
#include "count-arguments.h"
#include <stdio.h>
#define CONCAT(a, b) a ## b
#define CONCAT2(a, b) CONCAT(a, b)
#define DEBUG_VARIABLE_ARGUMENTS(FORMAT, ...) CONCAT2(DEBUG_, COUNT_ARGUMENTS(__VA_ARGS__))(FORMAT, ##__VA_ARGS__)
#define DEBUG_0(FORMAT) printf(FORMAT)
#define DEBUG_1(FORMAT, ARG1) printf(FORMAT, ARG1)
#define DEBUG_2(FORMAT, ARG1, ARG2) printf(FORMAT, ARG1, ARG2)
#define DEBUG_3(FORMAT, ARG1, ARG2, ARG3) printf(FORMAT, ARG1, ARG2, ARG3)