我有以下测试程序:
#define q "
int main() {
printf(q hello world q);
}
用 gcc 编译它(我在 Ubuntu 上尝试过版本 12.3 和 11.4)会产生以下错误: 第 1 行上的
error: missing terminating " character
。使用 clang(Apple clang 版本 11.0.0)编译会在第 4 行上产生错误 error: expected expression
。
现在,我一直假设,当编译 C 程序时,首先运行预处理器,处理所有预处理器指令,然后由编译器正确读取预处理器的输出。
通过 gcc 预处理器 (gcc -E) 运行此测试程序会产生警告,但没有错误,并产生以下合理的输出:
int main() {
printf(" hello world ");
}
该程序现在可以正确编译并运行良好。因此,虽然我无法直接编译原始程序,但如果我手动运行预处理器并编译结果,那么它就可以工作。这违反了我对预处理器和编译器如何一起运行的理解(显然是错误的)。
所以,我有两个问题:
是否可以在 C 宏的定义中包含双引号字符(不是两个)?
此示例中的预处理器和编译器发生了什么,如果我手动运行预处理器,则允许其编译和运行,但当预处理器作为编译过程的一部分自动运行时则不允许?
C 预处理器处理标记(和标记序列),而不是单个字符,标记化发生在预处理之前。这意味着您无法在预处理器中操作不是标记的内容 - 并且裸露的
"
不是标记,它是字符串文字标记的一部分。
通过使用更通用的宏处理器(如m4
),您可能可以得到更像您想要的东西