如何在 C 宏定义中包含双引号?

And*_*ill 3 c c-preprocessor

我有以下测试程序:

#define q "

int main() {
    printf(q hello world q);
}
Run Code Online (Sandbox Code Playgroud)

使用 gcc 编译此文件(我在 Ubuntu 上尝试过版本 12.3 和 11.4)会产生此错误: error: missing terminating " character在第 1 行。使用 clang(Apple clang 版本 11.0.0)编译会error: expected expression在第 4 行产生错误。

现在,我一直假设,当编译 C 程序时,预处理器首先运行,处理所有预处理器指令,然后编译器正确读取预处理器的输出。

通过 gcc 预处理器 (gcc -E) 运行此测试程序会产生警告,但不会出现错误,并产生以下合理的输出:

int main() {
    printf(" hello world ");
}
Run Code Online (Sandbox Code Playgroud)

现在,该程序将正确编译并运行良好。因此,虽然我无法直接编译原始程序,但如果我手动运行预处理器并编译结果,那么它就可以工作。这违反了我对预处理器和编译器如何一起运行的理解(显然是错误的)。

所以,我有两个问题:

  1. 是否可以在 C 宏的定义中包含双引号字符(但不能是两个)?

  2. 本示例中的预处理器和编译器发生了什么情况,如果我手动运行预处理器,则允许其编译和运行,但当预处理器作为编译过程的一部分自动运行时则不允许?

Chr*_*odd 10

C 预处理器处理标记(和标记序列),而不是单个字符,标记化发生在预处理之前。这意味着您无法在预处理器中操作不是标记的内容——并且裸露"不是标记,它是字符串文字标记的一部分。

通过使用更通用的宏处理器(如m4),您也许可以做一些更像您想要的事情