在宏中粘贴运算符

paste operator in macros

我找到了以下代码片段。

#define f(g,g2) g##g2
main() {

    int var12=100;
    printf("%d",f(var,12));

}

我知道这会将 f(var,12) 转换为 var12 。

我的问题在宏定义里,为什么他们不直接写成下面的:

#define f(g,g2) gg2

为什么我们需要 ## 来连接文本,而不是我们自己连接文本?

如果写 gg2 预处理器会将其视为单个标记。预处理器无法理解那是 gg2.

的串联
   #define f(g,g2) g##g2

我认为这是一段糟糕的不可读代码。它至少需要一个注释(给出一些动机、解释等...),像 f 这样的短名称是没有意义的。

My question is in the macro definition, why didn't they just write the following :

#define f(g,g2) gg2

使用这样的宏定义,f(x,y) 仍然会扩展为标记 gg2,即使作者希望扩展为 xy

请花时间阅读GNU cpp (and of your compiler, perhaps GCC) and later some C standard like n1570 或更好的文档。

还可以考虑通过(在某些情况下)生成 C 代码来设计您的软件(灵感来自 GNU bison, or GNU m4, or GPP). Your build machinery (e.g. your Makefile for GNU make) would process that as you want. In some cases (e.g. programs running for hours of CPU time), you might consider doing some partial evaluation and generating specialized code at runtime (for example, with libgccjit or GNU lightning). Pitrat's book on Artificial Beings, the conscience of a conscious machine 在整本书中解释和论证该想法。

不要忘记在编译器中启用所有警告和调试信息(例如 GCC use gcc -Wall -Wextra -g) and learn to use a debugger (like GNU gdb)。

在 Linux 系统上,我有时喜欢在运行时生成一些(或多或少是临时的)C 代码(来自某种 abstract syntax tree), then compile that code as a plugin, and dlopen(3) that plugin then dlsym(3) inside it. For a stupid example, see my manydl.c 程序(以证明您可以生成数十万个C文件和插件在同一个程序中。严肃的例子,看书吧。

您还可以阅读有关 Common Lisp or about Rust; both have a much richer macro 系统的书籍,而不是 C 提供的书籍。