我有两个宏,FOO2并且FOO3:
#define FOO2(x,y) ...
#define FOO3(x,y,z) ...
Run Code Online (Sandbox Code Playgroud)
我想定义一个新的宏FOO如下:
#define FOO(x,y) FOO2(x,y)
#define FOO(x,y,z) FOO3(x,y,z)
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为宏不会在参数数量上超载.
无需修改FOO2和FOO3,是有一些方法来定义一个宏FOO(使用__VA_ARGS__或以其他方式),以获得分派的相同的效果FOO(x,y)来FOO2,并FOO(x,y,z)到FOO3?
我想知道是否有可能迭代传递给C99中的可变参数宏或使用任何GCC扩展的参数?
例如,是否可以编写一个通用的宏,它接受一个结构,并将其字段作为参数传递,并打印结构中每个字段的偏移量?
像这样的东西:
struct a {
int a;
int b;
int c;
};
/* PRN_STRUCT_OFFSETS will print offset of each of the fields
within structure passed as the first argument.
*/
int main(int argc, char *argv[])
{
PRN_STRUCT_OFFSETS(struct a, a, b, c);
return 0;
}
考虑以下代码:
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) F(__VA_ARGS__)
F(1, 2, 3)
G(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
X = 1 and VA_ARGS = 2, 3两个宏的预期输出,这就是我用GCC得到的,但是,MSVC将其扩展为:
X = 1 and VA_ARGS = 2, 3
X = 1, 2, 3 and VA_ARGS =
Run Code Online (Sandbox Code Playgroud)
也就是说,__VA_ARGS__将其扩展为单个参数,而不是分解为多个参数.
有什么方法吗?
如何做这项工作?如何实现C99/C++ 11可变参数宏以根据给出多少参数来扩展到不同的东西?
是否有可能为一个特定的参数值以不同的方式扩展一个宏,对所有其他参数的扩展方式不同?
假设我定义了一个当前用户:
#define CURRENT_USER john_smith
Run Code Online (Sandbox Code Playgroud)
我希望能够做的是拥有一个宏,如果用户通过匹配,将以不同方式展开CURRENT_USER.请注意,我不知道所有可能的用户先验.最基本的案例:
#define IS_CURRENT_USER(user) \
/* this is not valid preprocessor macro */ \
#if user == CURRENT_USER \
1 \
#else \
0 \
#endif
Run Code Online (Sandbox Code Playgroud)
像宏一样,依赖于用户名的每个其他宏都可以按照以下方式完成:
#define SOME_USER_SPECIFIC_MACRO(user) SOME_USER_SPECIFIC_MACRO_SWITCH_1(IS_CURRENT_USER(user))
#define SOME_USER_SPECIFIC_MACRO_SWITCH_1(switch) SOME_USER_SPECIFIC_MACRO_SWITCH_2(switch) // expand switch ...
#define SOME_USER_SPECIFIC_MACRO_SWITCH_2(switch) SOME_USER_SPECIFIC_MACRO_##switch // ... and select specific case
#define SOME_USER_SPECIFIC_MACRO_0 ... // not current user
#define SOME_USER_SPECIFIC_MACRO_1 ... // current user
Run Code Online (Sandbox Code Playgroud)
这可能吗?
编辑:让我澄清一下.假设每个程序员CURRENT_USER在其配置头中定义了不同的.当且仅当他们的user参数匹配时,我希望用户特定的宏扩展到有意义的东西CURRENT_USER.因为我希望那些宏包含_pragmas,它不能进行运行时检查(如下面的一些anwsers中所提出的).
编辑:再次,澄清.假设有宏来禁用某些代码段的优化:
#define TURN_OPTIMISATION_OFF __pragma …Run Code Online (Sandbox Code Playgroud) 创建可变参数宏的技巧是什么FOO(a1, a2, a3,..., an),它可以扩展到您选择的任何预选有界范围内的FOOn(a1, a2, a3,..., an)值n?也就是说,FOO(a)应该扩展FOO1(a),FOO(a, b, c)对FOO3(a, b, c)等,我知道有一个标准的把戏,但我似乎无法找到它.
请随意将此问题标记为副本,如果答案中还有其他问题,请将其关闭.我怀疑有,但我找不到它.