You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C预处理器中字符串化宏且不展开已定义组件

解决方案:避免预处理器展开字符串宏中的已定义组件

核心问题根源

你遇到的问题本质是:当用-DFOO=GNU/linux这类无外层引号的方式传递参数时,预处理器会把linux当作独立标识符展开成预定义值;但如果传递的是带外层引号的字符串常量,内部的字符会被视为字符串内容,不会被预处理器解析为宏。

具体实现步骤

1. 在Automake中正确传递带引号的字符串

在Makefile.am里,通过shell转义传递带双引号的字符串参数:

AM_CPPFLAGS = -DFOO='"GNU/linux"'

GCC最终会收到-DFOO="GNU/linux",此时FOO被预处理器定义为字符串常量"GNU/linux",内部的linux是字符串的一部分,不会被展开。

2. 调整C代码直接使用宏

不需要再依赖双层STRINGIFY宏,直接将宏作为字符串常量使用即可:

#include <stdio.h>

int main() {
    printf("%s\n", FOO);
    return 0;
}

3. 兼容原有STRINGIFY宏的写法

如果现有代码必须保留STRINGIFY宏,可以修改宏定义为直接引用参数(避免触发额外展开):

#define STRINGIFY(x) x
const char *foo = STRINGIFY(FOO);

由于FOO本身已是字符串常量,STRINGIFY(FOO)会直接返回该常量,不会解析内部内容。

额外注意事项

  • 如果传递的字符串包含双引号,需要在Automake中额外转义,比如传递"GNU\"linux",要写成-DFOO='"GNU\\"linux"'。
  • 绝对不要使用-DFOO=GNU/linux这种无外层引号的写法,否则预处理器会把linux当作独立标识符展开。

内容的提问来源于stack exchange,提问作者umläute

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 23:05:28