具有零个或多个附加参数的可变参数宏
Variadic macros with zero or more additional arguments
我有一个用于检查某些测试方法结果的宏:
#define Eval(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }
我想在功能上得到这个:
Eval(Check_1(),"Check1 failed."); // case 1
Eval(Check_2()); // case 2
Eval(Check_3(), "some variable=%i", variableValue); // case 3
在案例 1 中,我想给用户 ("Check1 failed") 写评论,然后 return -1(可行)。
在案例 2 中,我只想从方法中 return,而不是为用户打印任何信息。所以我必须检测空注释的情况而不是调用 printf() - 这是行不通的。
如果任何 "Check_x" 方法失败,我需要通过 return 代码 -1;
退出当前方法
有什么方法可以用宏来实现吗?
这里有非常相似的问题:Standard alternative to GCC's ##VA_ARGS trick?,但我无法根据我的情况修改此代码。
编辑:
我使用 C99 标准。
在我的代码案例 2 的当前版本中编译时出现错误 "expected an expression"(我认为这是因为逗号和空参数)。
我还需要使用案例 3 来打印附加信息(变量值)。
所以,第二个参数实际上不是简单的字符串。
编辑2:
我得到了任务的解决方案。 Here I find it
// Macro to count of arguments
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
// Macro dispatcher
#define macro_dispatcher(func, ...) macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) func ## nargs
#define EVAL_UNIVERSAL(...) macro_dispatcher(EV, __VA_ARGS__)(__VA_ARGS__)
#define EV1(func) if (func == -1) return -1;
#define EV2(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }
#define EV3(func, ...) EV2(func, __VA_ARGS__)
#define EV4(func, ...) EV2(func, __VA_ARGS__)
#define EV5(func, ...) EV2(func, __VA_ARGS__)
#define EV6(func, ...) EV2(func, __VA_ARGS__)
#define EV7(func, ...) EV2(func, __VA_ARGS__)
我是这样使用的:
EVAL_UNIVERSAL(CheckInitialParameters());
EVAL_UNIVERSAL(CheckInitialParameters(), "text");
EVAL_UNIVERSAL(CheckInitialParameters(), "%i", 1);
EVAL_UNIVERSAL(CheckInitialParameters(), "%i %i", 1, 2);
非常感谢 Jens Gustedt 和 rmn (http://efesx.com/)
// Macro to count of arguments
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
// Macro dispatcher
#define macro_dispatcher(func, ...) macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) func ## nargs
#define EVAL_UNIVERSAL(...) macro_dispatcher(EV, __VA_ARGS__)(__VA_ARGS__)
#define EV1(func) if (func == -1) return -1;
#define EV2(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }
#define EV3(func, ...) EV2(func, __VA_ARGS__)
#define EV4(func, ...) EV2(func, __VA_ARGS__)
#define EV5(func, ...) EV2(func, __VA_ARGS__)
#define EV6(func, ...) EV2(func, __VA_ARGS__)
#define EV7(func, ...) EV2(func, __VA_ARGS__)
我是这样使用的:
EVAL_UNIVERSAL(CheckInitialParameters());
EVAL_UNIVERSAL(CheckInitialParameters(), "text");
EVAL_UNIVERSAL(CheckInitialParameters(), "%i", 1);
EVAL_UNIVERSAL(CheckInitialParameters(), "%i %i", 1, 2);
我有一个用于检查某些测试方法结果的宏:
#define Eval(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }
我想在功能上得到这个:
Eval(Check_1(),"Check1 failed."); // case 1
Eval(Check_2()); // case 2
Eval(Check_3(), "some variable=%i", variableValue); // case 3
在案例 1 中,我想给用户 ("Check1 failed") 写评论,然后 return -1(可行)。 在案例 2 中,我只想从方法中 return,而不是为用户打印任何信息。所以我必须检测空注释的情况而不是调用 printf() - 这是行不通的。
如果任何 "Check_x" 方法失败,我需要通过 return 代码 -1;
退出当前方法有什么方法可以用宏来实现吗?
这里有非常相似的问题:Standard alternative to GCC's ##VA_ARGS trick?,但我无法根据我的情况修改此代码。
编辑: 我使用 C99 标准。 在我的代码案例 2 的当前版本中编译时出现错误 "expected an expression"(我认为这是因为逗号和空参数)。 我还需要使用案例 3 来打印附加信息(变量值)。 所以,第二个参数实际上不是简单的字符串。
编辑2: 我得到了任务的解决方案。 Here I find it
// Macro to count of arguments
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
// Macro dispatcher
#define macro_dispatcher(func, ...) macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) func ## nargs
#define EVAL_UNIVERSAL(...) macro_dispatcher(EV, __VA_ARGS__)(__VA_ARGS__)
#define EV1(func) if (func == -1) return -1;
#define EV2(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }
#define EV3(func, ...) EV2(func, __VA_ARGS__)
#define EV4(func, ...) EV2(func, __VA_ARGS__)
#define EV5(func, ...) EV2(func, __VA_ARGS__)
#define EV6(func, ...) EV2(func, __VA_ARGS__)
#define EV7(func, ...) EV2(func, __VA_ARGS__)
我是这样使用的:
EVAL_UNIVERSAL(CheckInitialParameters());
EVAL_UNIVERSAL(CheckInitialParameters(), "text");
EVAL_UNIVERSAL(CheckInitialParameters(), "%i", 1);
EVAL_UNIVERSAL(CheckInitialParameters(), "%i %i", 1, 2);
非常感谢 Jens Gustedt 和 rmn (http://efesx.com/)
// Macro to count of arguments
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
// Macro dispatcher
#define macro_dispatcher(func, ...) macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) func ## nargs
#define EVAL_UNIVERSAL(...) macro_dispatcher(EV, __VA_ARGS__)(__VA_ARGS__)
#define EV1(func) if (func == -1) return -1;
#define EV2(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }
#define EV3(func, ...) EV2(func, __VA_ARGS__)
#define EV4(func, ...) EV2(func, __VA_ARGS__)
#define EV5(func, ...) EV2(func, __VA_ARGS__)
#define EV6(func, ...) EV2(func, __VA_ARGS__)
#define EV7(func, ...) EV2(func, __VA_ARGS__)
我是这样使用的:
EVAL_UNIVERSAL(CheckInitialParameters());
EVAL_UNIVERSAL(CheckInitialParameters(), "text");
EVAL_UNIVERSAL(CheckInitialParameters(), "%i", 1);
EVAL_UNIVERSAL(CheckInitialParameters(), "%i %i", 1, 2);