简体   繁体   English

在另一个宏中展开 X 宏

[英]Expand X macro inside another macro

I have a function that prints an output using fprintf() , and it uses a macro both for the format string and the parameters.我有一个使用fprintf()打印输出的函数,它使用一个宏来处理格式字符串和参数。 Since there are several places printing this info, this allows expanding the print while changing only one place.由于有多个位置打印此信息,因此可以在仅更改一个位置的同时扩展打印。

I want to generate a different print using the same data, but I want them to automatically expand together using an X-macro, but I can't get it to compile.我想使用相同的数据生成不同的打印,但我希望它们使用 X 宏自动扩展在一起,但我无法编译它。 I don't want there to be a need to edit the print every time I add something to print, or to wrap each print in ugly #define s.我不希望每次添加要打印的内容时都需要编辑打印,或者将每个打印都包裹在丑陋的#define

This program attempts to do what I want, but it doesn't compile:这个程序试图做我想做的事,但它不编译:

#include <stdio.h>

#define X(_a, _b, _c) \
    _a,

#define TABLE \
    X("abc", "123", "ddd") \
    X("def", "456", "aaa") \
    X("ghi", "789", "ddd") \
    
#define STUFF \
    TABLE

#undef X
    
int main()
{
    printf(" %s %s %s\n", STUFF);

    return 0;
}

(Idea is that STUFF prints one thing, and at another place i'll do a STUFF2 with a different column of the X macro called TABLE) (想法是 STUFF 打印一件事,在另一个地方,我将使用名为 TABLE 的 X 宏的不同列执行 STUFF2)

I get the following error:我收到以下错误:

main.c: In function 'main': main.c:在函数“main”中:

main.c:7:5: warning: implicit declaration of function 'X' [-Wimplicit-function-declaration] main.c:7:5: 警告:函数“X”的隐式声明 [-Wimplicit-function-declaration]

 X("abc", "123", "ddd") \\ ^

main.c:12:5: note: in expansion of macro 'TABLE' main.c:12:5: 注意:在宏 'TABLE' 的扩展中

TABLE ^~~~~

main.c:18:27: note: in expansion of macro 'STUFF' main.c:18:27: 注意:在宏 'STUFF' 的扩展中

printf(" %s %s %s\\n", STUFF); ^~~~~

main.c:8:5: error: expected ')' before 'X' main.c:8:5: 错误:'X' 之前的预期 ')'

 X("def", "456", "aaa") \\ ^

Undefining X before STUFF is expanded leads to … well X being undefined.在扩展STUFF之前取消定义X会导致……好吧X未定义。

For X macro to work, you have to undefine after having used it in some non-macro code (so it can expand)要使 X 宏工作,您必须在某些非宏代码中使用它取消定义(以便它可以扩展)

Once this is fixed, commas need to be moved in the list, else the last comma will trigger a syntax error ( error: expected ')' before 'X' ).修复此问题后,需要在列表中移动逗号,否则最后一个逗号将触发语法错误( error: expected ')' before 'X' )。 Same thing for the last backslash of TABLE TABLE的最后一个反斜杠也是如此

#include <stdio.h>

#define X(_a, _b, _c) \
    _a

#define TABLE \
    X("abc", "123", "ddd"), \
    X("def", "456", "aaa"), \
    X("ghi", "789", "ddd")

#define STUFF \
    TABLE
int main()
{
    printf(" %s %s %s\n", STUFF);

#undef X


    return 0;
}

this compiles, executes and prints abc def ghi这将编译、执行并打印abc def ghi

main.c:7:5: warning: implicit declaration of function 'X' [-Wimplicit-function-declaration] main.c:7:5: 警告:函数“X”的隐式声明 [-Wimplicit-function-declaration]

Well, yes.嗯,是。 At line 18, where macro STUFF appears, it is first expanded to在第 18 行,宏STUFF出现的地方,它首先被扩展为

TABLE

, then that is rescanned. ,然后重新扫描。 TABLE being defined as a macro, it, too, is expanded, resulting in TABLE被定义为一个宏,它也被扩展,导致

X("abc", "123", "ddd") X("def", "456", "aaa") X("ghi", "789", "ddd")

, then that is rescanned. 那么重新扫描。 But X is not defined as a macro (or as anything else) at that point, because you previously undef ined it.但此时X并未定义为宏(或其他任何内容),因为您之前undef它。 That leaves you with code that resembles three calls to an unknown function, without any kind of operator or separator between.这使您的代码类似于对未知函数的三个调用,之间没有任何类型的运算符或分隔符。 It is invalid.它是无效的。

Your X macro has to be defined appropriately at the place where it is expanded.你的 X 宏必须在它展开的地方适当地定义。 It does not need to be defined at all at the place where it appears in another macro's expansion text.它根本不需要在它出现在另一个宏的扩展文本中的地方定义。 You seem to have that backward.你好像落后了。


As discussed in comments, the objective is to be able to define separate macros, for example STUFF and STUFF2 that expand TABLE to consistent results that differ from each other.正如评论中所讨论的,目标是能够定义单独的宏,例如STUFFSTUFF2TABLE扩展为彼此不同的一致结果。 This is as opposed to causing STUFF to expand as wanted by manipulating the definition of X .这与通过操纵X的定义使STUFF根据需要扩展相反。

This can be accomplished by changing the definition of TABLE so that it is a function-like macro taking another macro name as an argument:这可以通过更改TABLE的定义来实现,使其成为一个类似函数的宏,以另一个宏名称作为参数:

#define TABLE(m) \
    m("abc", "123", "ddd") \
    m("def", "456", "aaa") \
    m("ghi", "789", "ddd")

The macros STUFF and STUFF2 can then control the expansion by their choice of which macro name to pass to TABLE() :然后,宏STUFFSTUFF2可以通过选择将哪个宏名称传递给TABLE()来控制扩展:

#define X(_a, _b, _c) _a
#define Y(_a, _b, _c) _b
#define STUFF TABLE(X)
#define STUFF2 TABLE(Y)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM