在 C 中生成宏?

发布于 2024-07-19 08:19:51 字数 555 浏览 4 评论 0原文

我想让 C 预处理器为我生成宏(即,我仅使用 C99)。 我会编写一个宏

#define make_macro(in) <...magic here...>

,当我

make_macro(name1)
make_macro(name2)

稍后将其放入代码中时,它将扩展为

#define name1(...) name1_fn(name1_info, __VA_ARGS__)
#define name2(...) name2_fn(name2_info, __VA_ARGS__)

,然后我就可以使用 name1 和 name2 作为(宏实现的)函数。 我认为我在这两个步骤中都坚持使用宏:使用宏重复重新填充模板是有意义的,并且除非通过宏,否则可变参数处理将不起作用。

那么<...这里的魔力...> 占位符来做到这一点? 此时,我开始相信这在 C99 中是不可能的,但也许我遗漏了一些语法细节。

I'd like to get the C preprocessor to generate macros for me (i.e., I'm using C99 only). I'd write a macro

#define make_macro(in) <...magic here...>

and when I put

make_macro(name1)
make_macro(name2)

later in the code, it would expand to

#define name1(...) name1_fn(name1_info, __VA_ARGS__)
#define name2(...) name2_fn(name2_info, __VA_ARGS__)

and I'd then be able to use name1 and name2 as (macro-implemented) functions. I think I'm stuck using macros at both steps: it makes sense to use a macro to repeatedly re-fill a template, and the variadic argument handling won't work except via a macro.

So what goes into the <...magic here...> placeholder to do this? At this point, I'm starting to believe that it's not possible in C99, but perhaps I'm missing some details of syntax.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

你曾走过我的故事 2024-07-26 08:19:51

这在标准 C 中是不可能的。

It's not possible in standard C.

抱着落日 2024-07-26 08:19:51

您考虑过使用 M4 宏吗?
我认为它们在大多数平台上都可用,因此这不应该成为限制。

M4 GNU 页面

Have you considered using M4 macros?
I think they are available on most platforms so that should not be a limitation.

M4 GNU page

琉璃繁缕 2024-07-26 08:19:51

正如大家所说,你无法完全按照你的要求去做。

您也许可以通过强制 C 预处理器运行两次来完成类似的操作,例如,在 makefile 中使用如下规则:

.c.pp:
   $(CPP) 
lt; -o $@

然后为您的文件提供 test.pp 扩展名。 Makefile将运行一次生成.c文件,然后对.c文件的正常运行将运行它第二次。

就我个人而言,我宁愿用 Perl 或其他语言编写外部脚本来为我生成 C 代码; 它比用 C 预处理器玩游戏要干净一些。 这取决于我们谈论的代码量。

As everybody has said, you can't do exactly what you are asking for.

You might be able to do something like that by forcing the C preprocesor to run twice, e.g., with a rule like this in the makefile:

.c.pp:
   $(CPP) 
lt; -o $@

Then give your file the extension of test.pp. The Makefile will run it once to generate the .c file, and then the normal run on the .c file will run it a second time.

Personally, I would rather write an external script in Perl or something to generate the C code for me; it's a bit cleaner than playing games with the C pre-processor. It depends on how much code we are talking about.

沫离伤花 2024-07-26 08:19:51

这是不可能的,因为宏只执行一次。

这并不意味着您不能在宏中使用其他宏,但您不能这样做

#define TEST #define HALLO 33

int x = TEST;

并期望 x 之后为 33!
你会得到一个语法错误,因为你尝试过

int x = #define HALLO 33;

或者编译器可能已经在#define中抱怨#define。

It's not possible because the macro is done only once.

This doesn't mean you could not use other macros in your macro but you could not do

#define TEST #define HALLO 33

int x = TEST;

and expect x to be 33 afterwards!
What you would get is a syntax error because you tried

int x = #define HALLO 33;

Or maybe the compiler already complains about #define in #define.

荒人说梦 2024-07-26 08:19:51

根据 C99 第 6.10.3.2 节 :

类函数宏的替换列表中的每个 # 预处理标记应为
后跟一个参数作为替换列表中的下一个预处理标记。

因此,如果您有一个名为 define 的参数,您当然可以在宏中放入 #define ,但它永远不会执行您想要的操作。 这经常让我烦恼,因为我必须使用 C 语言工作,因此不能使用 C++ 模板。

As per C99 Section 6.10.3.2:

Each # preprocessing token in the replacement list for a function-like macro shall be
followed by a parameter as the next preprocessing token in the replacement list.

So, you could certainly put a #define in a macro if you have a parameter named define but it will never do what you desire. This often bugs me since I have to work in C and as such can't use C++ templates.

弄潮 2024-07-26 08:19:51

尝试#define make_macro(name,...) name##_fn(name##_info, __VA_ARGS__)。

像这样使用:

make_macro(name1)
make_macro(name2,1)

这会生成

name1_fn(name1_info)
name2_fn(name2_info,1)

Try #define make_macro(name,...) name##_fn(name##_info, __VA_ARGS__).

Use like this:

make_macro(name1)
make_macro(name2,1)

and this would generate

name1_fn(name1_info)
name2_fn(name2_info,1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文