C 预处理器 - 现有定义的预置路径

C preprocessor - Prepending path for existing define

本文关键字:路径 定义 预处理 处理器      更新时间:2023-10-16

假设我有一个来自gcc -D选项的定义,例如

gcc -DBINDIR="/usr/bin"

我想要的是在这个现有定义前面附加一个路径,所以 BINDIR 类似于"/home/user/testbuild/usr/bin">

我尝试过:

#define STRINGIZE_NX(A)         #A
#define STRINGIZE(A)            STRINGIZE_NX(A)
#define PRE_PATH                "/home/user/testbuild"
#pragma message                 "PRE_PATH: " STRINGIZE(PRE_PATH)
#ifndef BINDIR
#   error "BINDIR must be defined"
#else
#   pragma message              "BINDIR: " STRINGIZE(BINDIR)
#   define TMP                  BINDIR
#   pragma message              "TMP: " STRINGIZE(TMP)
#   undef  BINDIR
#   define BINDIR               PRE_PATH TMP
#   pragma message              "BINDIR: " STRINGIZE(BINDIR)
#   undef  TMP
#endif

在查看编译器输出时,在我看来,TMP 没有按照我预期的方式分配给 BINDIR 的值:

note: #pragma message: PRE_PATH: "/home/user/testbuild"
note: #pragma message: BINDIR: "/usr/bin"
note: #pragma message: TMP: BINDIR
note: #pragma message: "/home/user/testbuild" BINDIR

最后编译器将在定义应该连接的地方失败:

error: expected ')' before 'TMP'
#  define BINDIR    PRE_PATH TMP

我做错了什么?

感谢所有的帮助!

修改宏的值而不丢失其初始值是不可能的。您必须记住,定义宏并不等同于赋值给变量。在后一种情况下,计算右侧表达式,并分配结果值。在前一种情况下,您为一系列标记定义一个名称(宏(,在展开宏之前不会评估这些标记。因此,当您定义它时:

#define TMP BINDIR

TMP宏不"包含"路径"/usr/bin",它包含"BINDIR",字面意思。当TMP展开时,它扩展到BINDIR,而又扩展到"/usr/bin"。当你取消定义BINDIR时,它的值会丢失,TMP扩展将只产生"BINDIR"。

您可以做的是对完整路径使用不同的宏而不是BINDIR.像这样:

#define FULL_BINDIR PRE_PATH BINDIR

我知道这不是你所要求的。但是,与其做晦涩的预处理器魔术,不如将以下内容放入头文件:

#undef BIN_DIR
#define BIN_DIR bin_dir
extern char *bin_dir;

以及代码文件之一和之前包含上述标头:

char *bin_dir = PRE_PATH BIN_DIR;